FHM29052601IBL - integrate merge gateway
This commit is contained in:
@@ -52,3 +52,4 @@ defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
$route['default_controller'] = 'welcome';
|
||||
$route['404_override'] = '';
|
||||
$route['translate_uri_dashes'] = FALSE;
|
||||
$route['report/(:num)'] = 'tools/merge_report/preview/$1';
|
||||
|
||||
@@ -7,11 +7,12 @@ class Done extends MY_Controller
|
||||
echo "SampleStorage API";
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('Ibl_merge_report_gateway');
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
@@ -100,69 +101,52 @@ class Done extends MY_Controller
|
||||
exit;
|
||||
}
|
||||
|
||||
function mergereport()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
$prm = $this->sys_input;
|
||||
$userid = $this->sys_user['M_UserID'];
|
||||
$name = $prm['name'];
|
||||
$urls = $prm['urls'];
|
||||
|
||||
$data = [
|
||||
"name" => $name,
|
||||
"urls" => $urls
|
||||
];
|
||||
$jsonData = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
// Validasi URL
|
||||
if (empty($urls) || !is_array($urls)) {
|
||||
$this->sys_error("Invalid URLs");
|
||||
exit;
|
||||
}
|
||||
|
||||
// Escape string agar aman untuk query SQL
|
||||
$jsonDataEscaped = $this->db_onedev->escape($jsonData);
|
||||
|
||||
// Masukkan ke dalam query dengan string yang sudah di-escape
|
||||
$sql = "INSERT INTO merge_request (mergeRequestPayload) VALUES ($jsonDataEscaped)";
|
||||
// Menyiapkan dan menjalankan query menggunakan parameter binding
|
||||
$this->db_onedev->query($sql);
|
||||
|
||||
// // Mengambil ID dari entri terakhir yang disisipkan
|
||||
$lastInsertId = $this->db_onedev->insert_id();
|
||||
|
||||
|
||||
|
||||
$sql_gateway = "SELECT S_SystemsMergeReportGateway FROM conf_systems
|
||||
WHERE S_SystemsIsActive = 'Y' LIMIT 1";
|
||||
$qry_gateway = $this->db_onedev->query($sql_gateway);
|
||||
$rows = $qry_gateway->result_array();
|
||||
$new_url='';
|
||||
|
||||
|
||||
// $url_prefix = getUrlPrefixOnly();
|
||||
// $new_url = $url_prefix . "report/" . $lastInsertId;
|
||||
if(!empty($rows[0]['S_SystemsMergeReportGateway'])){
|
||||
$new_url=$rows[0]['S_SystemsMergeReportGateway']. "report/". $lastInsertId;
|
||||
|
||||
}
|
||||
|
||||
$record = [
|
||||
"data" => $jsonDataEscaped,
|
||||
"last_id" => $lastInsertId,
|
||||
"url" => $new_url,
|
||||
];
|
||||
|
||||
$result = array(
|
||||
"total" => 1,
|
||||
"records" => array('status' => 'OK', 'records' => $record),
|
||||
);
|
||||
$this->sys_ok($result);
|
||||
// exit;
|
||||
}
|
||||
function mergereport()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
$prm = $this->sys_input;
|
||||
$userid = $this->sys_user['M_UserID'];
|
||||
$labNumber = isset($prm['T_OrderHeaderLabNumber']) ? trim($prm['T_OrderHeaderLabNumber']) : '';
|
||||
if ($labNumber === '' && isset($prm['nolab'])) {
|
||||
$labNumber = trim($prm['nolab']);
|
||||
}
|
||||
$name = isset($prm['name']) ? trim($prm['name']) : '';
|
||||
|
||||
if ($labNumber === '') {
|
||||
$this->sys_error("LAB_NUMBER_REQUIRED - T_OrderHeaderLabNumber wajib diisi");
|
||||
exit;
|
||||
}
|
||||
|
||||
$resultMerge = $this->ibl_merge_report_gateway->create_merge_request_from_lab_number(
|
||||
$labNumber,
|
||||
$userid,
|
||||
$name
|
||||
);
|
||||
|
||||
if ($resultMerge['status'] !== 'OK') {
|
||||
$this->sys_error($resultMerge['code'] . " - " . $resultMerge['message']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$record = [
|
||||
"last_id" => $resultMerge['data']['mergeRequestID'],
|
||||
"url" => $resultMerge['data']['previewUrl'],
|
||||
"T_OrderHeaderID" => $resultMerge['data']['T_OrderHeaderID'],
|
||||
"T_OrderHeaderLabNumber" => $resultMerge['data']['T_OrderHeaderLabNumber'],
|
||||
"snapshot" => $resultMerge['data']['snapshot'],
|
||||
"go_payload_preview" => $resultMerge['data']['goPayloadPreview'],
|
||||
];
|
||||
|
||||
$result = array(
|
||||
"total" => 1,
|
||||
"records" => array('status' => 'OK', 'records' => $record),
|
||||
);
|
||||
$this->sys_ok($result);
|
||||
exit;
|
||||
}
|
||||
function dosend()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
@@ -294,4 +278,4 @@ class Done extends MY_Controller
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
44
application/controllers/tools/Ibl_merge_report_admin.http
Normal file
44
application/controllers/tools/Ibl_merge_report_admin.http
Normal file
@@ -0,0 +1,44 @@
|
||||
### Operasional create merge_request dari nomor lab
|
||||
POST http://10.9.20.31/one-api-lab/mockup/fo/mergeemailv1/done/mergereport
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"T_OrderHeaderLabNumber": "{{lab_number}}"
|
||||
}
|
||||
|
||||
### Admin create merge_request baru
|
||||
POST http://10.9.20.31/one-api-lab/tools/ibl_merge_report_admin/create_request
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"T_OrderHeaderLabNumber": "{{lab_number}}"
|
||||
}
|
||||
|
||||
### Admin preview via backend tools
|
||||
POST http://10.9.20.31/one-api-lab/tools/ibl_merge_report_admin/preview
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"T_OrderHeaderLabNumber": "{{lab_number}}",
|
||||
"mergeRequestID": {{merge_request_id}}
|
||||
}
|
||||
|
||||
### Public preview stream via gateway
|
||||
GET http://10.9.20.31/one-api-lab/report/{{merge_request_id}}?T_OrderHeaderLabNumber={{lab_number}}
|
||||
|
||||
### Direct test ke service Go jika nanti sudah hidup
|
||||
POST http://127.0.0.1:8005/merge
|
||||
Content-Type: application/json
|
||||
X-Internal-Secret: {{merge_secret}}
|
||||
|
||||
{
|
||||
"name": "IBL12345-JOHN-DOE-merge-report.pdf",
|
||||
"urls": [
|
||||
"https://devone.aplikasi.web.id/birt/frameset?__report=report/onelab/lab/rpt_test_email.rptdesign&__format=pdf&username=admin&PID=123&ts=1716963662"
|
||||
],
|
||||
"mergeRequestID": 1036,
|
||||
"T_OrderHeaderID": 123
|
||||
}
|
||||
84
application/controllers/tools/Ibl_merge_report_admin.php
Normal file
84
application/controllers/tools/Ibl_merge_report_admin.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
class Ibl_merge_report_admin extends MY_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->library('Ibl_merge_report_gateway');
|
||||
}
|
||||
|
||||
public function create_request()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
exit;
|
||||
}
|
||||
|
||||
$auth = $this->ibl_merge_report_gateway->is_admin_group_allowed($this->sys_user['M_UserID']);
|
||||
if ($auth['status'] !== 'OK') {
|
||||
$this->sys_error($auth['code'] . ' - ' . $auth['message']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$labNumber = isset($this->sys_input['T_OrderHeaderLabNumber']) ? trim($this->sys_input['T_OrderHeaderLabNumber']) : '';
|
||||
if ($labNumber === '' && isset($this->sys_input['nolab'])) {
|
||||
$labNumber = trim($this->sys_input['nolab']);
|
||||
}
|
||||
if ($labNumber === '') {
|
||||
$this->sys_error('LAB_NUMBER_REQUIRED - T_OrderHeaderLabNumber wajib diisi.');
|
||||
exit;
|
||||
}
|
||||
|
||||
$customName = isset($this->sys_input['name']) ? trim($this->sys_input['name']) : '';
|
||||
$result = $this->ibl_merge_report_gateway->create_merge_request_from_lab_number(
|
||||
$labNumber,
|
||||
$this->sys_user['M_UserID'],
|
||||
$customName
|
||||
);
|
||||
|
||||
if ($result['status'] !== 'OK') {
|
||||
$this->sys_error($result['code'] . ' - ' . $result['message']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok($result['data']);
|
||||
exit;
|
||||
}
|
||||
|
||||
public function preview()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
exit;
|
||||
}
|
||||
|
||||
$auth = $this->ibl_merge_report_gateway->is_admin_group_allowed($this->sys_user['M_UserID']);
|
||||
if ($auth['status'] !== 'OK') {
|
||||
$this->sys_error($auth['code'] . ' - ' . $auth['message']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$mergeRequestId = isset($this->sys_input['mergeRequestID']) ? (int) $this->sys_input['mergeRequestID'] : 0;
|
||||
$labNumber = isset($this->sys_input['T_OrderHeaderLabNumber']) ? trim($this->sys_input['T_OrderHeaderLabNumber']) : '';
|
||||
if ($labNumber === '' && isset($this->sys_input['nolab'])) {
|
||||
$labNumber = trim($this->sys_input['nolab']);
|
||||
}
|
||||
if ($mergeRequestId <= 0) {
|
||||
$this->sys_error('MERGE_REQUEST_ID_REQUIRED - mergeRequestID wajib diisi.');
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $this->ibl_merge_report_gateway->stream_merge_request($mergeRequestId, $labNumber);
|
||||
if ($result['status'] !== 'OK') {
|
||||
$this->sys_error($result['code'] . ' - ' . $result['message']);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $result['data']['payload']['name'] . '"');
|
||||
echo $result['data']['body'];
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -5,43 +5,39 @@ class Merge_report extends MY_Controller {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->load->database();
|
||||
$this->load->library('Ibl_merge_report_gateway');
|
||||
}
|
||||
|
||||
public function get($id = null) {
|
||||
header('Content-Type: application/json');
|
||||
$this->preview($id);
|
||||
}
|
||||
|
||||
try {
|
||||
if ($id === null || !is_numeric($id)) {
|
||||
throw new Exception('Invalid or missing ID parameter.');
|
||||
}
|
||||
|
||||
$query = $this->db
|
||||
->select('mergeRequestPayload')
|
||||
->where('mergeRequestID', $id)
|
||||
->get('merge_request');
|
||||
|
||||
if ($query->num_rows() === 0) {
|
||||
throw new Exception('Record not found.');
|
||||
}
|
||||
|
||||
$row = $query->row();
|
||||
$payload = json_decode($row->mergeRequestPayload, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new Exception('Invalid JSON in mergeRequestPayload.');
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'status' => 'OK',
|
||||
'data' => $payload
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
public function preview($id = null) {
|
||||
if ($id === null || !is_numeric($id)) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'status' => 'ERR',
|
||||
'message' => $e->getMessage()
|
||||
'message' => 'MERGE_REQUEST_ID_INVALID - mergeRequestID tidak valid.'
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$labNumber = isset($_GET['T_OrderHeaderLabNumber']) ? trim($_GET['T_OrderHeaderLabNumber']) : '';
|
||||
if ($labNumber === '' && isset($_GET['nolab'])) {
|
||||
$labNumber = trim($_GET['nolab']);
|
||||
}
|
||||
$result = $this->ibl_merge_report_gateway->stream_merge_request((int) $id, $labNumber);
|
||||
if ($result['status'] !== 'OK') {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'status' => 'ERR',
|
||||
'message' => $result['code'] . ' - ' . $result['message']
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $result['data']['payload']['name'] . '"');
|
||||
echo $result['data']['body'];
|
||||
}
|
||||
}
|
||||
|
||||
709
application/libraries/Ibl_merge_report_gateway.php
Normal file
709
application/libraries/Ibl_merge_report_gateway.php
Normal file
@@ -0,0 +1,709 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
class Ibl_merge_report_gateway
|
||||
{
|
||||
protected $CI;
|
||||
protected $db_onedev;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->CI = &get_instance();
|
||||
$this->db_onedev = $this->CI->load->database('onedev', true);
|
||||
}
|
||||
|
||||
public function create_merge_request_from_lab_number($labNumber, $creatorUserId, $customName = '')
|
||||
{
|
||||
$order = $this->resolve_order_by_lab_number($labNumber);
|
||||
if (!$order) {
|
||||
return $this->error('ORDER_NOT_FOUND', 'Nomor lab tidak ditemukan.');
|
||||
}
|
||||
|
||||
return $this->create_merge_request_from_order($order['T_OrderHeaderID'], $creatorUserId, $customName);
|
||||
}
|
||||
|
||||
public function create_merge_request_from_order($orderHeaderId, $creatorUserId, $customName = '')
|
||||
{
|
||||
$order = $this->get_order_header($orderHeaderId);
|
||||
if (!$order) {
|
||||
return $this->error('ORDER_NOT_FOUND', 'Order tidak ditemukan.');
|
||||
}
|
||||
|
||||
$composition = $this->compose_merge_request_payload($orderHeaderId, $customName);
|
||||
if ($composition['status'] !== 'OK') {
|
||||
return $composition;
|
||||
}
|
||||
|
||||
$payloadJson = json_encode($composition['data']['snapshot'], JSON_UNESCAPED_SLASHES);
|
||||
$insert = $this->db_onedev->query(
|
||||
"INSERT INTO merge_request (
|
||||
mergeRequestT_OrderHeaderID,
|
||||
mergeRequestPayload,
|
||||
mergeRequestCreatedUserID,
|
||||
mergeRequestCreated
|
||||
) VALUES (?, ?, ?, NOW())",
|
||||
array(
|
||||
$orderHeaderId,
|
||||
$payloadJson,
|
||||
$creatorUserId
|
||||
)
|
||||
);
|
||||
|
||||
if (!$insert) {
|
||||
return $this->error('MERGE_REQUEST_INSERT_FAILED', 'Gagal menyimpan merge request.');
|
||||
}
|
||||
|
||||
$mergeRequestId = (int) $this->db_onedev->insert_id();
|
||||
$previewUrl = $this->build_preview_url($mergeRequestId);
|
||||
|
||||
$goPayload = $this->build_go_payload_from_snapshot(
|
||||
$mergeRequestId,
|
||||
$orderHeaderId,
|
||||
$composition['data']['snapshot']
|
||||
);
|
||||
|
||||
return array(
|
||||
'status' => 'OK',
|
||||
'data' => array(
|
||||
'mergeRequestID' => $mergeRequestId,
|
||||
'T_OrderHeaderID' => (int) $orderHeaderId,
|
||||
'T_OrderHeaderLabNumber' => $order['T_OrderHeaderLabNumber'],
|
||||
'previewUrl' => $previewUrl,
|
||||
'snapshot' => $composition['data']['snapshot'],
|
||||
'goPayloadPreview' => $goPayload
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function compose_merge_request_payload($orderHeaderId, $customName = '')
|
||||
{
|
||||
$order = $this->get_order_header($orderHeaderId);
|
||||
if (!$order) {
|
||||
return $this->error('ORDER_NOT_FOUND', 'Order tidak ditemukan.');
|
||||
}
|
||||
|
||||
$summary = $this->get_merge_summary_by_order_id($orderHeaderId);
|
||||
if ($summary['status'] !== 'OK') {
|
||||
return $summary;
|
||||
}
|
||||
|
||||
if ($summary['data']['available_merge'] !== 'Y') {
|
||||
return $this->error('MERGE_NOT_READY', 'Order belum siap untuk merge report.');
|
||||
}
|
||||
|
||||
$sources = array();
|
||||
$sourceDedup = array();
|
||||
|
||||
foreach ($summary['data']['records'] as $group) {
|
||||
if (empty($group['group_result_ids'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($group['group_result_ids'] as $groupResultId) {
|
||||
$groupSources = $this->get_group_sources(
|
||||
$order,
|
||||
(int) $groupResultId
|
||||
);
|
||||
|
||||
if ($groupSources['status'] !== 'OK') {
|
||||
return $groupSources;
|
||||
}
|
||||
|
||||
foreach ($groupSources['data'] as $source) {
|
||||
if ($source['relativeUrl'] === '') {
|
||||
return $this->error('MERGE_SOURCE_MISSING', 'Salah satu sumber report belum tersedia.');
|
||||
}
|
||||
|
||||
if (isset($sourceDedup[$source['absoluteUrl']])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sourceDedup[$source['absoluteUrl']] = true;
|
||||
$sources[] = $source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($sources) === 0) {
|
||||
return $this->error('MERGE_SOURCE_EMPTY', 'Tidak ada sumber report yang bisa digabung.');
|
||||
}
|
||||
|
||||
$fileName = $this->build_merge_filename($order, $customName);
|
||||
$snapshot = array(
|
||||
'name' => $fileName,
|
||||
'T_OrderHeaderID' => (int) $order['T_OrderHeaderID'],
|
||||
'T_OrderHeaderLabNumber' => $order['T_OrderHeaderLabNumber'],
|
||||
'createdAt' => date('Y-m-d H:i:s'),
|
||||
'sources' => $sources
|
||||
);
|
||||
|
||||
return array(
|
||||
'status' => 'OK',
|
||||
'data' => array(
|
||||
'snapshot' => $snapshot,
|
||||
'summary' => $summary['data']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function get_merge_summary_by_lab_number($labNumber)
|
||||
{
|
||||
$order = $this->resolve_order_by_lab_number($labNumber);
|
||||
if (!$order) {
|
||||
return $this->error('ORDER_NOT_FOUND', 'Nomor lab tidak ditemukan.');
|
||||
}
|
||||
|
||||
return $this->get_merge_summary_by_order_id($order['T_OrderHeaderID']);
|
||||
}
|
||||
|
||||
public function get_merge_summary_by_order_id($orderHeaderId)
|
||||
{
|
||||
$sql = "SELECT
|
||||
T_OrderHeaderID,
|
||||
T_OrderDetailID,
|
||||
Group_ResultID,
|
||||
Nat_GroupName,
|
||||
Group_ResultName,
|
||||
T_OrderDetailT_TestName,
|
||||
T_OrderDetailT_TestIsResult,
|
||||
So_ResultEntryID,
|
||||
IF(T_OrderPromiseDateTime > NOW(), 'N', 'Y') AS statuspromise,
|
||||
DATE_FORMAT(T_OrderPromiseDateTime,'%d-%m-%Y %H:%i') as promise_date
|
||||
FROM t_orderheader
|
||||
JOIN t_orderdetail ON T_OrderHeaderID = T_OrderDetailT_OrderHeaderID
|
||||
AND T_OrderDetailIsActive = 'Y'
|
||||
AND T_OrderHeaderID = ?
|
||||
AND T_OrderHeaderIsActive = 'Y'
|
||||
AND T_OrderDetailT_TestIsResult = 'Y'
|
||||
JOIN group_resultdetail ON T_OrderDetailT_TestID = Group_ResultDetailT_TestID
|
||||
AND Group_ResultDetailIsActive = 'Y'
|
||||
JOIN group_result ON Group_ResultDetailGroup_ResultID = Group_ResultID
|
||||
AND Group_ResultIsActive = 'Y'
|
||||
JOIN t_orderpromise ON T_OrderHeaderID = T_OrderPromiseT_OrderHeaderID
|
||||
AND T_OrderPromiseIsActive = 'Y'
|
||||
AND T_OrderDetailT_OrderPromiseID = T_OrderPromiseID
|
||||
JOIN t_test ON T_OrderDetailT_TestID = T_TestID
|
||||
AND T_TestIsActive = 'Y'
|
||||
JOIN nat_group ON T_TestNat_GroupID = Nat_GroupID
|
||||
AND Nat_GroupIsActive = 'Y'
|
||||
JOIN t_orderdelivery ON T_OrderDeliveryT_OrderHeaderID = T_OrderHeaderID
|
||||
AND T_OrderDeliveryM_DeliveryTypeID = 3
|
||||
AND T_OrderDeliveryIsActive = 'Y'
|
||||
LEFT JOIN so_resultentry ON T_OrderHeaderID = So_ResultEntryT_OrderHeaderID
|
||||
AND T_OrderDetailID = So_ResultEntryT_OrderDetailID
|
||||
AND So_ResultEntryIsActive = 'Y'
|
||||
ORDER BY Nat_GroupID, promise_date";
|
||||
|
||||
$query = $this->db_onedev->query($sql, array($orderHeaderId));
|
||||
if (!$query) {
|
||||
return $this->error('MERGE_SUMMARY_FAILED', 'Gagal membaca komposisi merge order.');
|
||||
}
|
||||
|
||||
$rows = $query->result_array();
|
||||
if (count($rows) === 0) {
|
||||
return $this->error('MERGE_SUMMARY_EMPTY', 'Order tidak memiliki komposisi merge.');
|
||||
}
|
||||
|
||||
$grouped = array();
|
||||
foreach ($rows as $row) {
|
||||
$groupName = $row['Nat_GroupName'];
|
||||
if (!isset($grouped[$groupName])) {
|
||||
$grouped[$groupName] = array(
|
||||
'group' => $groupName,
|
||||
'ohid' => (int) $row['T_OrderHeaderID'],
|
||||
'statuspromise' => true,
|
||||
'promises' => array(),
|
||||
'orderdetailid' => array(),
|
||||
'resultnames' => array(),
|
||||
'details' => array(),
|
||||
'group_result_ids' => array()
|
||||
);
|
||||
}
|
||||
|
||||
if ($row['statuspromise'] !== 'Y') {
|
||||
$grouped[$groupName]['statuspromise'] = false;
|
||||
}
|
||||
|
||||
if (!in_array($row['promise_date'], $grouped[$groupName]['promises'])) {
|
||||
$grouped[$groupName]['promises'][] = $row['promise_date'];
|
||||
}
|
||||
|
||||
$grouped[$groupName]['orderdetailid'][] = (int) $row['T_OrderDetailID'];
|
||||
|
||||
if (!in_array($row['Group_ResultName'], $grouped[$groupName]['resultnames'])) {
|
||||
$grouped[$groupName]['resultnames'][] = $row['Group_ResultName'];
|
||||
}
|
||||
|
||||
if (!in_array((int) $row['Group_ResultID'], $grouped[$groupName]['group_result_ids'])) {
|
||||
$grouped[$groupName]['group_result_ids'][] = (int) $row['Group_ResultID'];
|
||||
}
|
||||
|
||||
if (!isset($grouped[$groupName]['details'][$row['Group_ResultName']])) {
|
||||
$grouped[$groupName]['details'][$row['Group_ResultName']] = array(
|
||||
'name' => $row['Group_ResultName'],
|
||||
'resultentryid' => array()
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_null($row['So_ResultEntryID'])) {
|
||||
$grouped[$groupName]['details'][$row['Group_ResultName']]['resultentryid'][] = (int) $row['So_ResultEntryID'];
|
||||
}
|
||||
}
|
||||
|
||||
$records = array();
|
||||
$countTotalGroup = count($grouped);
|
||||
$countDoneGroup = 0;
|
||||
foreach ($grouped as $group) {
|
||||
if ($group['statuspromise']) {
|
||||
$countDoneGroup++;
|
||||
}
|
||||
|
||||
$detailList = array();
|
||||
foreach ($group['details'] as $detail) {
|
||||
$detailList[] = $detail;
|
||||
}
|
||||
$group['details'] = $detailList;
|
||||
$records[] = $group;
|
||||
}
|
||||
|
||||
$availableMerge = 'Y';
|
||||
if ($countTotalGroup === 1) {
|
||||
if ($countDoneGroup < 1) {
|
||||
$availableMerge = 'N';
|
||||
}
|
||||
} elseif ($countTotalGroup >= 2) {
|
||||
if ($countDoneGroup < 2 || $countDoneGroup < $countTotalGroup) {
|
||||
$availableMerge = 'N';
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'status' => 'OK',
|
||||
'data' => array(
|
||||
'total' => 0,
|
||||
'records' => $records,
|
||||
'available_merge' => $availableMerge
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function stream_merge_request($mergeRequestId, $labNumber = '')
|
||||
{
|
||||
$mergeRequest = $this->get_merge_request($mergeRequestId);
|
||||
if (!$mergeRequest) {
|
||||
return $this->error('MERGE_REQUEST_NOT_FOUND', 'Merge request tidak ditemukan.');
|
||||
}
|
||||
|
||||
$payload = json_decode($mergeRequest['mergeRequestPayload'], true);
|
||||
if (!is_array($payload)) {
|
||||
return $this->error('MERGE_REQUEST_INVALID', 'Payload merge request tidak valid.');
|
||||
}
|
||||
|
||||
$order = $this->get_order_header($mergeRequest['mergeRequestT_OrderHeaderID']);
|
||||
if (!$order) {
|
||||
return $this->error('ORDER_NOT_FOUND', 'Order untuk merge request tidak ditemukan.');
|
||||
}
|
||||
|
||||
if ($labNumber !== '') {
|
||||
$resolvedOrder = $this->resolve_order_by_lab_number($labNumber);
|
||||
if (!$resolvedOrder || (int) $resolvedOrder['T_OrderHeaderID'] !== (int) $mergeRequest['mergeRequestT_OrderHeaderID']) {
|
||||
return $this->error('MERGE_REQUEST_ORDER_MISMATCH', 'Merge request tidak terkait dengan nomor lab tersebut.');
|
||||
}
|
||||
}
|
||||
|
||||
$goPayload = $this->build_go_payload_from_snapshot(
|
||||
(int) $mergeRequest['mergeRequestID'],
|
||||
(int) $mergeRequest['mergeRequestT_OrderHeaderID'],
|
||||
$payload
|
||||
);
|
||||
|
||||
return $this->call_merge_service($goPayload);
|
||||
}
|
||||
|
||||
public function build_go_payload_from_snapshot($mergeRequestId, $orderHeaderId, array $snapshot)
|
||||
{
|
||||
$urls = array();
|
||||
foreach ($snapshot['sources'] as $source) {
|
||||
$urls[] = $this->make_absolute_url($source['relativeUrl']);
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => $snapshot['name'],
|
||||
'urls' => $urls,
|
||||
'mergeRequestID' => (int) $mergeRequestId,
|
||||
'T_OrderHeaderID' => (int) $orderHeaderId
|
||||
);
|
||||
}
|
||||
|
||||
public function get_current_user_group_id($userId)
|
||||
{
|
||||
$query = $this->db_onedev->query(
|
||||
"SELECT M_UserM_UserGroupID FROM m_user WHERE M_UserID = ? AND M_UserIsActive = 'Y' LIMIT 1",
|
||||
array($userId)
|
||||
);
|
||||
|
||||
if (!$query || $query->num_rows() === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int) $query->row()->M_UserM_UserGroupID;
|
||||
}
|
||||
|
||||
public function is_admin_group_allowed($userId)
|
||||
{
|
||||
$config = $this->get_system_config();
|
||||
$allowed = array();
|
||||
if (!empty($config['S_SystemsMergeReportAdminGroupIDs'])) {
|
||||
foreach (explode(',', $config['S_SystemsMergeReportAdminGroupIDs']) as $value) {
|
||||
$value = (int) trim($value);
|
||||
if ($value > 0) {
|
||||
$allowed[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($allowed) === 0) {
|
||||
return array(
|
||||
'status' => 'ERR',
|
||||
'code' => 'MERGE_ADMIN_GROUP_NOT_CONFIGURED',
|
||||
'message' => 'Akses admin merge report belum dikonfigurasi.'
|
||||
);
|
||||
}
|
||||
|
||||
$groupId = $this->get_current_user_group_id($userId);
|
||||
if (!in_array($groupId, $allowed)) {
|
||||
return array(
|
||||
'status' => 'ERR',
|
||||
'code' => 'MERGE_ADMIN_FORBIDDEN',
|
||||
'message' => 'User group tidak diizinkan mengakses tools merge report.'
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'status' => 'OK',
|
||||
'data' => array(
|
||||
'groupId' => $groupId,
|
||||
'allowedGroupIds' => $allowed
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function get_system_config()
|
||||
{
|
||||
static $config = null;
|
||||
if ($config !== null) {
|
||||
return $config;
|
||||
}
|
||||
|
||||
$query = $this->db_onedev->query(
|
||||
"SELECT
|
||||
S_SystemsMergeReportGateway,
|
||||
S_SystemIPAddressRegional,
|
||||
S_SystemsMergeReportServiceBaseUrl,
|
||||
S_SystemsMergeReportServiceSecret,
|
||||
S_SystemsMergeReportAdminGroupIDs
|
||||
FROM conf_systems
|
||||
WHERE S_SystemsIsActive = 'Y'
|
||||
LIMIT 1"
|
||||
);
|
||||
|
||||
if ($query && $query->num_rows() > 0) {
|
||||
$config = $query->row_array();
|
||||
} else {
|
||||
$config = array();
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected function get_merge_request($mergeRequestId)
|
||||
{
|
||||
$query = $this->db_onedev->query(
|
||||
"SELECT
|
||||
mergeRequestID,
|
||||
mergeRequestT_OrderHeaderID,
|
||||
mergeRequestPayload,
|
||||
mergeRequestCreatedUserID,
|
||||
mergeRequestCreated
|
||||
FROM merge_request
|
||||
WHERE mergeRequestID = ?
|
||||
LIMIT 1",
|
||||
array($mergeRequestId)
|
||||
);
|
||||
|
||||
if (!$query || $query->num_rows() === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $query->row_array();
|
||||
}
|
||||
|
||||
protected function get_order_header($orderHeaderId)
|
||||
{
|
||||
$sql = "SELECT
|
||||
T_OrderHeaderID,
|
||||
T_OrderHeaderLabNumber,
|
||||
T_OrderHeaderLabNumberExt,
|
||||
DATE(T_OrderHeaderDate) AS order_date,
|
||||
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(CONCAT(IFNULL(M_TitleName,''),' ',M_PatientName), ' ', '-'), '.', '_'), '(', ''), ')', ''), '\\'', '') AS patient_name
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
WHERE T_OrderHeaderID = ?
|
||||
AND T_OrderHeaderIsActive = 'Y'
|
||||
LIMIT 1";
|
||||
$query = $this->db_onedev->query($sql, array($orderHeaderId));
|
||||
if (!$query || $query->num_rows() === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $query->row_array();
|
||||
}
|
||||
|
||||
protected function resolve_order_by_lab_number($labNumber)
|
||||
{
|
||||
$query = $this->db_onedev->query(
|
||||
"SELECT T_OrderHeaderID, T_OrderHeaderLabNumber
|
||||
FROM t_orderheader
|
||||
WHERE T_OrderHeaderLabNumber = ?
|
||||
AND T_OrderHeaderIsActive = 'Y'
|
||||
ORDER BY T_OrderHeaderID DESC
|
||||
LIMIT 1",
|
||||
array($labNumber)
|
||||
);
|
||||
|
||||
if (!$query || $query->num_rows() === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $query->row_array();
|
||||
}
|
||||
|
||||
protected function get_group_sources(array $order, $groupResultId)
|
||||
{
|
||||
$query = $this->db_onedev->query(
|
||||
"SELECT DISTINCT
|
||||
Group_ResultID,
|
||||
Group_ResultName,
|
||||
Group_ResultFlagNonLab,
|
||||
IFNULL(T_EmailNonLabUrl,'-') AS EmailNonLabUrl,
|
||||
IF(T_EmailNonLabUrl IS NULL AND Group_ResultFlagNonLab = 'Y',' [Belum Pilih Format Hasil]','') AS temail
|
||||
FROM t_orderdetail
|
||||
JOIN group_resultdetail
|
||||
ON Group_ResultDetailT_TestID = T_OrderDetailT_TestID
|
||||
AND T_OrderDetailIsActive = 'Y'
|
||||
AND Group_ResultDetailIsActive = 'Y'
|
||||
AND T_OrderDetailT_OrderHeaderID = ?
|
||||
JOIN group_result
|
||||
ON Group_ResultDetailGroup_ResultID = Group_ResultID
|
||||
AND Group_ResultIsActive = 'Y'
|
||||
AND Group_ResultID = ?
|
||||
LEFT JOIN t_email_nonlab
|
||||
ON T_EmailNonLabT_OrderHeaderID = T_OrderDetailT_OrderHeaderID
|
||||
AND T_EmailNonLabType LIKE CONCAT('%', REPLACE(Group_ResultName, 'Elektromedik', 'electromedis'), '%')",
|
||||
array($order['T_OrderHeaderID'], $groupResultId)
|
||||
);
|
||||
|
||||
if (!$query) {
|
||||
return $this->error('MERGE_SOURCE_QUERY_FAILED', 'Gagal menyusun sumber report.');
|
||||
}
|
||||
|
||||
$rows = $query->result_array();
|
||||
$result = array();
|
||||
$ts = '&ts=' . time();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$relativeUrl = '';
|
||||
$emailNonLabUrl = str_replace(' ', '', $row['EmailNonLabUrl']);
|
||||
if (strpos($emailNonLabUrl, 'fisik') !== false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ((int) $row['Group_ResultID']) {
|
||||
case 1:
|
||||
$relativeUrl = '/birt/frameset?__report=report/onelab/lab/rpt_test_email.rptdesign&__format=pdf&username=admin&PID=' . $order['T_OrderHeaderID'] . $ts;
|
||||
break;
|
||||
case 2:
|
||||
$relativeUrl = '/birt/frameset?__report=report/onelab/lab/rpt_hasil_papsmear_email.rptdesign&__format=pdf&username=admin&PID=' . $order['T_OrderHeaderID'] . $ts;
|
||||
break;
|
||||
case 3:
|
||||
$relativeUrl = '/birt/frameset?__report=report/onelab/lab/rpt_hasil_fna_email.rptdesign&__format=pdf&username=admin&PID=' . $order['T_OrderHeaderID'] . $ts;
|
||||
break;
|
||||
case 12:
|
||||
$relativeUrl = '/birt/frameset?__report=report/onelab/lab/rpt_hasil_lcprep_email.rptdesign&__format=pdf&username=admin&PID=' . $order['T_OrderHeaderID'] . $ts;
|
||||
break;
|
||||
case 13:
|
||||
$relativeUrl = '/birt/frameset?__report=report/onelab/lab/rpt_test_mikro_email.rptdesign&__format=pdf&username=admin&PID=' . $order['T_OrderHeaderID'] . $ts;
|
||||
break;
|
||||
case 14:
|
||||
$relativeUrl = '/birt/frameset?__report=report/onelab/lab/rpt_hasil_cytologi_email.rptdesign&__format=pdf&username=admin&PID=' . $order['T_OrderHeaderID'] . $ts;
|
||||
break;
|
||||
default:
|
||||
$relativeUrl = $emailNonLabUrl;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($relativeUrl === '-' || $relativeUrl === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[] = array(
|
||||
'groupResultID' => (int) $row['Group_ResultID'],
|
||||
'name' => $row['Group_ResultName'],
|
||||
'relativeUrl' => $relativeUrl,
|
||||
'absoluteUrl' => $this->make_absolute_url($relativeUrl)
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'status' => 'OK',
|
||||
'data' => $result
|
||||
);
|
||||
}
|
||||
|
||||
protected function call_merge_service(array $payload)
|
||||
{
|
||||
$config = $this->get_system_config();
|
||||
$baseUrl = isset($config['S_SystemsMergeReportServiceBaseUrl']) ? trim($config['S_SystemsMergeReportServiceBaseUrl']) : '';
|
||||
$secret = isset($config['S_SystemsMergeReportServiceSecret']) ? trim($config['S_SystemsMergeReportServiceSecret']) : '';
|
||||
|
||||
if ($baseUrl === '' || $secret === '') {
|
||||
return $this->error('MERGE_SERVICE_NOT_CONFIGURED', 'Konfigurasi merge report service belum lengkap.');
|
||||
}
|
||||
|
||||
$url = rtrim($baseUrl, '/') . '/merge';
|
||||
$jsonPayload = json_encode($payload, JSON_UNESCAPED_SLASHES);
|
||||
$lastError = array(
|
||||
'status' => 'ERR',
|
||||
'code' => 'MERGE_SERVICE_FAILED',
|
||||
'message' => 'Layanan merge internal gagal memproses permintaan.'
|
||||
);
|
||||
|
||||
for ($attempt = 1; $attempt <= 3; $attempt++) {
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, array(
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $jsonPayload,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_HTTPHEADER => array(
|
||||
'Content-Type: application/json',
|
||||
'X-Internal-Secret: ' . $secret
|
||||
),
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_CONNECTTIMEOUT => 30
|
||||
));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$curlError = curl_error($ch);
|
||||
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$headerSize = (int) curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
$contentType = (string) curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false || $curlError !== '') {
|
||||
$lastError = $this->error('MERGE_SERVICE_TIMEOUT', 'Layanan merge internal melebihi batas waktu.');
|
||||
continue;
|
||||
}
|
||||
|
||||
$headers = substr($response, 0, $headerSize);
|
||||
$body = substr($response, $headerSize);
|
||||
|
||||
if ($httpCode >= 200 && $httpCode < 300 && stripos($contentType, 'application/pdf') !== false) {
|
||||
return array(
|
||||
'status' => 'OK',
|
||||
'data' => array(
|
||||
'headers' => $headers,
|
||||
'contentType' => $contentType,
|
||||
'body' => $body,
|
||||
'payload' => $payload
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$lastError = $this->map_service_error($httpCode);
|
||||
}
|
||||
|
||||
return $lastError;
|
||||
}
|
||||
|
||||
protected function map_service_error($httpCode)
|
||||
{
|
||||
if ($httpCode === 400 || $httpCode === 422) {
|
||||
return $this->error('MERGE_SERVICE_REJECTED', 'Komposisi merge report tidak valid.');
|
||||
}
|
||||
|
||||
if ($httpCode === 401 || $httpCode === 403) {
|
||||
return $this->error('MERGE_SERVICE_UNAUTHORIZED', 'Layanan merge internal menolak permintaan.');
|
||||
}
|
||||
|
||||
if ($httpCode === 404) {
|
||||
return $this->error('MERGE_SOURCE_NOT_FOUND', 'Salah satu sumber report tidak ditemukan.');
|
||||
}
|
||||
|
||||
if ($httpCode === 408 || $httpCode === 504) {
|
||||
return $this->error('MERGE_SERVICE_TIMEOUT', 'Layanan merge internal melebihi batas waktu.');
|
||||
}
|
||||
|
||||
return $this->error('MERGE_SERVICE_FAILED', 'Layanan merge internal gagal memproses permintaan.');
|
||||
}
|
||||
|
||||
protected function build_preview_url($mergeRequestId)
|
||||
{
|
||||
return rtrim($this->get_public_base_url(), '/') . '/report/' . (int) $mergeRequestId;
|
||||
}
|
||||
|
||||
protected function make_absolute_url($url)
|
||||
{
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('/^https?:\/\//i', $url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
return rtrim($this->get_public_base_url(), '/') . '/' . ltrim($url, '/');
|
||||
}
|
||||
|
||||
protected function get_public_base_url()
|
||||
{
|
||||
$config = $this->get_system_config();
|
||||
if (!empty($config['S_SystemsMergeReportGateway'])) {
|
||||
return rtrim($config['S_SystemsMergeReportGateway'], '/');
|
||||
}
|
||||
|
||||
$https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
$script = isset($_SERVER['SCRIPT_NAME']) ? dirname($_SERVER['SCRIPT_NAME']) : '';
|
||||
$script = trim(str_replace('\\', '/', $script), '/');
|
||||
if ($script === '' || $script === '.') {
|
||||
return $https . '://' . $host;
|
||||
}
|
||||
|
||||
return $https . '://' . $host . '/' . $script;
|
||||
}
|
||||
|
||||
protected function build_merge_filename(array $order, $customName)
|
||||
{
|
||||
$name = trim($customName);
|
||||
if ($name === '') {
|
||||
$name = $order['T_OrderHeaderLabNumber'] . '-' . $order['patient_name'] . '-merge-report.pdf';
|
||||
}
|
||||
|
||||
if (strtolower(substr($name, -4)) !== '.pdf') {
|
||||
$name .= '.pdf';
|
||||
}
|
||||
|
||||
return preg_replace('/[^A-Za-z0-9._-]/', '-', $name);
|
||||
}
|
||||
|
||||
protected function error($code, $message)
|
||||
{
|
||||
return array(
|
||||
'status' => 'ERR',
|
||||
'code' => $code,
|
||||
'message' => $message
|
||||
);
|
||||
}
|
||||
}
|
||||
110
docs/merge-report-service-setup.md
Normal file
110
docs/merge-report-service-setup.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Merge Report Service Setup
|
||||
|
||||
Dokumen ini untuk aktivasi integrasi:
|
||||
|
||||
- FE -> one-api-lab -> `ibl_merge_report_service`
|
||||
- one-api-lab menjadi merge gateway
|
||||
- service Go hanya menerima `POST /merge`
|
||||
|
||||
## 1. Config DB
|
||||
|
||||
Isi kolom berikut di `one_lab.conf_systems`:
|
||||
|
||||
- `S_SystemsMergeReportServiceBaseUrl`
|
||||
- `S_SystemsMergeReportServiceSecret`
|
||||
- `S_SystemsMergeReportAdminGroupIDs`
|
||||
|
||||
Contoh query:
|
||||
|
||||
```sql
|
||||
UPDATE conf_systems
|
||||
SET
|
||||
S_SystemsMergeReportServiceBaseUrl = 'http://127.0.0.1:8005',
|
||||
S_SystemsMergeReportServiceSecret = 'ganti-dengan-shared-secret',
|
||||
S_SystemsMergeReportAdminGroupIDs = '1'
|
||||
WHERE S_SystemsID = 1;
|
||||
```
|
||||
|
||||
Catatan:
|
||||
|
||||
- `S_SystemsMergeReportServiceBaseUrl` jangan diakhiri slash.
|
||||
- `S_SystemsMergeReportAdminGroupIDs` diisi daftar `M_UserGroupID` dipisah koma.
|
||||
- `S_SystemsMergeReportGateway` tetap dipakai untuk membentuk absolute URL source PDF dan preview URL.
|
||||
|
||||
## 2. Kontrak Service Go
|
||||
|
||||
Endpoint minimal yang harus tersedia:
|
||||
|
||||
- `POST /merge`
|
||||
|
||||
Request:
|
||||
|
||||
Headers:
|
||||
|
||||
- `Content-Type: application/json`
|
||||
- `X-Internal-Secret: <shared-secret>`
|
||||
|
||||
Body:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "IBL12345-JOHN-DOE-merge-report.pdf",
|
||||
"urls": [
|
||||
"https://devone.aplikasi.web.id/birt/frameset?__report=report/onelab/lab/rpt_test_email.rptdesign&__format=pdf&username=admin&PID=123&ts=1716963662"
|
||||
],
|
||||
"mergeRequestID": 1036,
|
||||
"T_OrderHeaderID": 123
|
||||
}
|
||||
```
|
||||
|
||||
Expected response:
|
||||
|
||||
- sukses: `200` dengan body binary PDF dan `Content-Type: application/pdf`
|
||||
- gagal validasi/source: `400` atau `422`
|
||||
- secret salah: `401` atau `403`
|
||||
- source tidak ditemukan: `404`
|
||||
- timeout/upstream: `408` atau `504`
|
||||
|
||||
Perilaku yang wajib:
|
||||
|
||||
- jika satu source gagal, seluruh merge gagal
|
||||
- tidak ada cache file/artifact dulu
|
||||
- fresh generate only
|
||||
|
||||
## 3. Endpoint one-api-lab
|
||||
|
||||
Operasional:
|
||||
|
||||
- `POST /mockup/fo/mergeemailv1/done/mergereport`
|
||||
|
||||
Input minimal:
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "<jwt>",
|
||||
"T_OrderHeaderLabNumber": "IBL12345"
|
||||
}
|
||||
```
|
||||
|
||||
Admin create snapshot:
|
||||
|
||||
- `POST /tools/ibl_merge_report_admin/create_request`
|
||||
|
||||
Admin preview:
|
||||
|
||||
- `POST /tools/ibl_merge_report_admin/preview`
|
||||
|
||||
Public preview/stream:
|
||||
|
||||
- `GET /report/{mergeRequestID}`
|
||||
|
||||
## 4. Verifikasi
|
||||
|
||||
Checklist setelah service Go siap:
|
||||
|
||||
1. `mergereport` insert row baru di `merge_request`.
|
||||
2. Row `merge_request` menyimpan `mergeRequestT_OrderHeaderID`.
|
||||
3. Row `merge_request` menyimpan `mergeRequestCreatedUserID`.
|
||||
4. `/report/{id}` mengembalikan PDF, bukan JSON payload lama.
|
||||
5. Error dari Go dipetakan ke pesan aman dari one-api-lab.
|
||||
6. Admin tool gagal jika `M_UserGroupID` tidak masuk whitelist config.
|
||||
12
sql/manual_changes/2026-05-29-merge-report-gateway.sql
Normal file
12
sql/manual_changes/2026-05-29-merge-report-gateway.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
ALTER TABLE merge_request
|
||||
ADD COLUMN mergeRequestT_OrderHeaderID INT NULL AFTER mergeRequestID,
|
||||
ADD COLUMN mergeRequestCreatedUserID INT NULL AFTER mergeRequestPayload;
|
||||
|
||||
ALTER TABLE merge_request
|
||||
ADD INDEX idx_merge_request_order (mergeRequestT_OrderHeaderID),
|
||||
ADD INDEX idx_merge_request_created_user (mergeRequestCreatedUserID);
|
||||
|
||||
ALTER TABLE conf_systems
|
||||
ADD COLUMN S_SystemsMergeReportServiceBaseUrl VARCHAR(255) NULL AFTER S_SystemsMergeReportGateway,
|
||||
ADD COLUMN S_SystemsMergeReportServiceSecret VARCHAR(255) NULL AFTER S_SystemsMergeReportServiceBaseUrl,
|
||||
ADD COLUMN S_SystemsMergeReportAdminGroupIDs VARCHAR(255) NULL AFTER S_SystemsMergeReportServiceSecret;
|
||||
@@ -0,0 +1,6 @@
|
||||
UPDATE conf_systems
|
||||
SET
|
||||
S_SystemsMergeReportServiceBaseUrl = 'http://127.0.0.1:8005',
|
||||
S_SystemsMergeReportServiceSecret = 'ganti-dengan-shared-secret',
|
||||
S_SystemsMergeReportAdminGroupIDs = '1'
|
||||
WHERE S_SystemsID = 1;
|
||||
Reference in New Issue
Block a user