Files
BE_IBL/application/controllers/mockup/godicomupreq/Godicomupreq.php
2026-04-15 15:24:12 +07:00

695 lines
26 KiB
PHP

<?php
class Godicomupreq extends MY_Controller {
/**
* Class untuk mengelola data upload request DICOM File ke Google Healthcare
*/
private $table = 'godicom_uprequest';
// TODO: add ohif_hostname config to Database
private $ohif_hostname = 'http://152.42.173.210:3000/';
var $db_onedev;
public function __construct() {
parent::__construct();
$this->db_onedev = $this->load->database("onedev", true);
}
/**
* Retrieves upload requests based on the provided filters.
*/
public function get_uprequests(){
try {
$startDate = $this->input->get('startDate');
$endDate = $this->input->get('endDate');
$status = $this->input->get('status');
// Validate date input
if (!$startDate || !$endDate) {
throw new Exception("Date parameter needed");
}
if (!DateTime::createFromFormat('Y-m-d', $startDate) || !DateTime::createFromFormat('Y-m-d', $endDate)) {
throw new Exception("Invalid date format should be in yyyy-mm-dd");
}
if ($startDate > $endDate) {
throw new Exception("Start date should be less than end date");
}
$startDate .= ' 00:00:00';
$endDate .= ' 23:59:59';
$sql = "SELECT * FROM $this->table WHERE GdcUpreq_DicomUpStatus = ? AND GdcUpreq_Created BETWEEN ? AND ? AND GdcUpreq_IsActive = 'Y'";
$query = $this->db_onedev->query($sql, array($status, $startDate, $endDate));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
$result = $query->result_array();
$this->sys_ok($result);
exit;
} catch (Exception $e) {
$this->sys_error($e->getMessage());
exit;
}
}
/**
* Update GdcUpreq_DicomUpStatus and GdcUpreq_DicomUpRetry based on Gateway * Progress.
*/
public function update_dicom_upstatus(){
try {
$prm = $this->sys_input;
$upreqId = $prm['GdcUpreqID'];
$dicomStatus = $prm['GdcUpreq_DicomUpStatus'];
$shortcode_uri = $prm['GdcUpreq_ShortCodeUrl'];
// This line ensures proper URL concatenation regardless of whether the hostname has a
// trailing slash or the shortcode URI has a leading slash
$shortlink = rtrim($this->ohif_hostname, '/') . '/' . ltrim($shortcode_uri, '/');
// validation $dicomStatus should be 0,1,2,3
if (!in_array($dicomStatus, [0, 1, 2, 3])) {
throw new Exception("Invalid status value");
}
$this->db_onedev->trans_start();
$sql = "UPDATE $this->table SET
GdcUpreq_DicomUpStatus = ?,
GdcUpreq_DicomUpRetry = GdcUpreq_DicomUpRetry + 1,
GdcUpreq_ShortCodeUrl = ?
WHERE GdcUpreqID = ?";
$query = $this->db_onedev->query($sql, [$dicomStatus, $shortlink, $upreqId]);
// Check any transaction error
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
// Check if transaction was successful
if ($this->db_onedev->trans_status() === FALSE) {
throw new Exception("Transaction failed in update_dicom_upstatus");
}
if ($this->db_onedev->affected_rows() > 0) {
$this->db_onedev->trans_complete();
$this->sys_ok('Update successful');
exit;
} else {
throw new Exception("No rows affected");
}
} catch (Exception $e) {
$this->db_onedev->trans_rollback();
$this->sys_error($e->getMessage());
exit;
}
}
/**
* Insert GdcUpreq record from t_mwl_order
* based on T_MwlOrder_AccessionNo
* @param string $accession_no
*/
public function create_uprequest(){
try {
$prm = $this->sys_input;
$accession_no = $prm['AccessionNo'];
// Validation
if (empty($accession_no)) {
throw new Exception("Accession Number are required");
}
// Modality = take first 2 letters of $accession_no
$modality = substr($accession_no, 0, 2);
$this->db_onedev->trans_start();
// Check if any record exists with the same Accession No
$sqlCheck = "SELECT * FROM $this->table WHERE GdcUpreq_AccessionNo = ? AND GdcUpreq_IsActive = 'Y'";
$queryCheck = $this->db_onedev->query($sqlCheck, [$accession_no]);
if (!$queryCheck) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
if ($queryCheck->num_rows() > 0) {
throw new Exception("Accession Number already exists");
}
// Query t_mwl_result based on Accession No
$sql = "SELECT * FROM t_mwl_result
JOIN t_mwl_order ON T_MwlResult_AccessionNo = T_MwlOrder_AccessionNo
WHERE T_MwlResult_AccessionNo = ? AND T_MwlResultIsActive = 'Y'";
$query = $this->db_onedev->query($sql, [$accession_no]);
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
if ($query->num_rows() == 0) {
throw new Exception("Accession Number not found");
}
$orderData = $query->row();
// Query Patient Data Based on T_MwlResultM_PatientNoReg
$sqlPatient = "SELECT M_PatientName, M_PatientDOB, M_PatientM_SexID, M_SexCode
FROM m_patient
JOIN m_sex ON M_PatientM_SexID = M_SexID
WHERE M_PatientNoReg = ? AND M_PatientIsActive = 'Y'";
$queryPatient = $this->db_onedev->query($sqlPatient, [$orderData->T_MwlResultM_PatientNoReg]);
if( !$queryPatient) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
if( $queryPatient->num_rows() == 0) {
throw new Exception("Patient data not found");
}
$patientData = $queryPatient->row();
// Query Branch Code
$sqlBranch = "SELECT M_BranchCode FROM m_branch WHERE M_BranchIsDefault = 'Y' AND M_BranchIsActive = 'Y'";
$queryBranch = $this->db_onedev->query($sqlBranch);
if (!$queryBranch) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
if ($queryBranch->num_rows() > 0) {
$branchCode = $queryBranch->row()->M_BranchCode;
} else {
$branchCode = null; // Default to null if no default branch found
}
// Insert
$sqlInsert = "INSERT INTO $this->table (
GdcUpreq_AccessionNo,
GdcUpreqM_PatientNoReg,
GdcUpreq_PjM_DoctorID,
GdcUpreq_SenderM_DoctorID,
GdcUpreq_StudyDescription,
GdcUpreq_StudyIUID,
GdcUpreq_SeriesIUID,
GdcUpreq_SopIUID,
GdcUpreqM_PatientName,
GdcUpreqM_PatientDOB,
GdcUpreqM_PatientM_SexCode,
GdcUpdreq_ModalityCode,
GdcUpreqM_BranchCode,
GdcUpreq_IsActive
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$query = $this->db_onedev->query($sqlInsert, [
$accession_no,
$orderData->T_MwlResultM_PatientNoReg,
$orderData->T_MwlOrderPjM_DoctorID,
$orderData->T_MwlOrderSenderM_DoctorID,
$orderData->T_MwlResult_StudyDescription,
$orderData->T_MwlResult_StudyIUID,
$orderData->T_MwlResult_SeriesIUID,
$orderData->T_MwlResult_SopIUID,
$patientData->M_PatientName,
$patientData->M_PatientDOB,
$patientData->M_SexCode,
$modality,
$branchCode,
'Y' // Default IsActive
]);
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
// Get the last inserted ID
$insert_id = $this->db_onedev->insert_id();
// Query the inserted record
$sqlSelect = "SELECT * FROM $this->table WHERE GdcUpreqID = ?";
$querySelect = $this->db_onedev->query($sqlSelect, [$insert_id]);
if (!$querySelect) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
if ($querySelect->num_rows() == 0) {
throw new Exception("Insert failed, record not found");
}
$insertedRecord = $querySelect->row_array();
if ($this->db_onedev->trans_status() === FALSE) {
throw new Exception("Transaction failed in create_uprequest");
}
$this->db_onedev->trans_complete();
if ($insert_id) {
$this->sys_ok([
'msg' => 'Insert successful',
'records' => $insertedRecord
]);
exit;
} else {
throw new Exception("Insert failed");
}
} catch (Exception $e) {
$this->sys_error($e->getMessage());
}
}
/**
* Get all upRequest records with optional filtering
*
* @param array $filters Associative array of field => value pairs for filtering
* @param int $limit Number of records to return
* @param int $offset Starting position for fetching records
* @param string $order_by Field to order by
* @param string $order_direction Direction of ordering (ASC or DESC)
* @return array|bool Array of upRequest records or FALSE on error
*/
public function get_all_uprequests($filters = array(), $limit = NULL, $offset = NULL, $order_by = 'GdcUpreqID', $order_direction = 'DESC') {
try {
$sql = "SELECT * FROM {$this->table} WHERE 1=1";
// Add filters
foreach ($filters as $field => $value) {
$sql .= " AND {$field} = " . $this->db_onedev->escape($value);
}
// Add ordering
$sql .= " ORDER BY {$order_by} {$order_direction}";
// Add limit and offset
if ($limit !== NULL) {
$sql .= " LIMIT ";
if ($offset !== NULL) {
$sql .= $offset . ", ";
}
$sql .= $limit;
}
$query = $this->db_onedev->query($sql);
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
return $query->result_array();
} catch (Exception $e) {
log_message('error', 'Error in get_all_uprequests: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Get a single upRequest record by ID
*
* @param int $id The GdcUpreqID to fetch
* @return array|null|bool The upRequest record, null if not found, or FALSE on error
*/
public function get_uprequest_by_id($id) {
try {
$sql = "SELECT * FROM {$this->table} WHERE GdcUpreqID = ?";
$query = $this->db_onedev->query($sql, array($id));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
return ($query->num_rows() > 0) ? $query->row_array() : NULL;
} catch (Exception $e) {
log_message('error', 'Error in get_uprequest_by_id: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Get upRequests by accession number
*
* @param string $accession_no The accession number
* @return array|bool Array of matching upRequest records or FALSE on error
*/
public function get_uprequests_by_accession($accession_no) {
try {
$sql = "SELECT * FROM {$this->table} WHERE GdcUpreq_AccessionNo = ?";
$query = $this->db_onedev->query($sql, array($accession_no));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
return $query->result_array();
} catch (Exception $e) {
log_message('error', 'Error in get_uprequests_by_accession: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Get upRequests by patient registration number
*
* @param string $patient_no The patient registration number
* @return array|bool Array of matching upRequest records or FALSE on error
*/
public function get_uprequests_by_patient($patient_no) {
try {
$sql = "SELECT * FROM {$this->table} WHERE GdcUpreqM_PatientNoReg = ?";
$query = $this->db_onedev->query($sql, array($patient_no));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
return $query->result_array();
} catch (Exception $e) {
log_message('error', 'Error in get_uprequests_by_patient: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Get upRequests by upload status
*
* @param int $status The upload status code (0:Pending, 1:Process, 2:Sent, 3:Failed)
* @param string $type The type of upload status to check ('dicom' or 'metadata')
* @return array|bool Array of matching upRequest records or FALSE on error
*/
public function get_uprequests_by_status($status, $type = 'dicom') {
try {
$field = ($type == 'dicom') ? 'GdcUpreq_DicomUpStatus' : 'GdcUpreq_MetadataUpStatus';
$sql = "SELECT * FROM {$this->table} WHERE {$field} = ? AND GdcUpreq_IsActive = 'Y'";
$query = $this->db_onedev->query($sql, array($status));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
return $query->result_array();
} catch (Exception $e) {
log_message('error', 'Error in get_uprequests_by_status: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Create a new upRequest record
*
* @param array $data The data to insert
* @return int|bool The inserted ID on success, false on failure
*/
public function create_uprequest_ai($data) {
try {
// Build field list and value list
$fields = array();
$values = array();
$placeholders = array();
foreach ($data as $field => $value) {
$fields[] = $field;
$values[] = $value;
$placeholders[] = '?';
}
$field_list = implode(', ', $fields);
$placeholder_list = implode(', ', $placeholders);
$sql = "INSERT INTO {$this->table} ({$field_list}) VALUES ({$placeholder_list})";
// Start transaction
$this->db_onedev->trans_start();
$query = $this->db_onedev->query($sql, $values);
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
$insert_id = $this->db_onedev->insert_id();
// Complete transaction
$this->db_onedev->trans_complete();
// Check if transaction was successful
if ($this->db_onedev->trans_status() === FALSE) {
throw new Exception("Transaction failed in create_uprequest");
}
return $insert_id;
} catch (Exception $e) {
if ($this->db_onedev->trans_status() !== FALSE) {
$this->db_onedev->trans_rollback();
}
log_message('error', 'Error in create_uprequest: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Update an existing upRequest record
*
* @param int $id The ID of the record to update
* @param array $data The data to update
* @return bool True on success, false on failure
*/
public function update_uprequest($id, $data) {
try {
// Build SET clause
$set_pairs = array();
$values = array();
foreach ($data as $field => $value) {
$set_pairs[] = "{$field} = ?";
$values[] = $value;
}
$set_clause = implode(', ', $set_pairs);
// Add ID to values
$values[] = $id;
$sql = "UPDATE {$this->table} SET {$set_clause} WHERE GdcUpreqID = ?";
// Start transaction
$this->db_onedev->trans_start();
$query = $this->db_onedev->query($sql, $values);
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
// Complete transaction
$this->db_onedev->trans_complete();
// Check if transaction was successful
if ($this->db_onedev->trans_status() === FALSE) {
throw new Exception("Transaction failed in update_uprequest");
}
return ($this->db_onedev->affected_rows() > 0);
} catch (Exception $e) {
if ($this->db_onedev->trans_status() !== FALSE) {
$this->db_onedev->trans_rollback();
}
log_message('error', 'Error in update_uprequest: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Update upload status of a request
*
* @param int $id The ID of the record to update
* @param int $status The new status (0:Pending, 1:Process, 2:Sent, 3:Failed)
* @param string $type The type of status to update ('dicom' or 'metadata')
* @return bool True on success, false on failure
*/
public function update_upload_status($id, $status, $type = 'dicom') {
try {
$status_field = ($type == 'dicom') ? 'GdcUpreq_DicomUpStatus' : 'GdcUpreq_MetadataUpStatus';
$retry_field = ($type == 'dicom') ? 'GdcUpreq_DicomUpRetry' : 'GdcUpreq_MetadataUpRetry';
$sql = "UPDATE {$this->table} SET
{$status_field} = ?,
{$retry_field} = IF({$status_field} = 3, {$retry_field} + 1, {$retry_field})
WHERE GdcUpreqID = ?";
// Start transaction
$this->db_onedev->trans_start();
$query = $this->db_onedev->query($sql, array($status, $id));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
// Complete transaction
$this->db_onedev->trans_complete();
// Check if transaction was successful
if ($this->db_onedev->trans_status() === FALSE) {
throw new Exception("Transaction failed in update_upload_status");
}
return ($this->db_onedev->affected_rows() > 0);
} catch (Exception $e) {
if ($this->db_onedev->trans_status() !== FALSE) {
$this->db_onedev->trans_rollback();
}
log_message('error', 'Error in update_upload_status: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Soft delete an upRequest record by setting IsActive to 'N'
*
* @param int $id The ID of the record to delete
* @return bool True on success, false on failure
*/
public function soft_delete_uprequest($id) {
try {
$sql = "UPDATE {$this->table} SET GdcUpreq_IsActive = 'N' WHERE GdcUpreqID = ?";
// Start transaction
$this->db_onedev->trans_start();
$query = $this->db_onedev->query($sql, array($id));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
// Complete transaction
$this->db_onedev->trans_complete();
// Check if transaction was successful
if ($this->db_onedev->trans_status() === FALSE) {
throw new Exception("Transaction failed in soft_delete_uprequest");
}
return ($this->db_onedev->affected_rows() > 0);
} catch (Exception $e) {
if ($this->db_onedev->trans_status() !== FALSE) {
$this->db_onedev->trans_rollback();
}
log_message('error', 'Error in soft_delete_uprequest: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Hard delete an upRequest record (permanent removal)
*
* @param int $id The ID of the record to delete
* @return bool True on success, false on failure
*/
public function delete_uprequest($id) {
try {
$sql = "DELETE FROM {$this->table} WHERE GdcUpreqID = ?";
// Start transaction
$this->db_onedev->trans_start();
$query = $this->db_onedev->query($sql, array($id));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
// Complete transaction
$this->db_onedev->trans_complete();
// Check if transaction was successful
if ($this->db_onedev->trans_status() === FALSE) {
throw new Exception("Transaction failed in delete_uprequest");
}
return ($this->db_onedev->affected_rows() > 0);
} catch (Exception $e) {
if ($this->db_onedev->trans_status() !== FALSE) {
$this->db_onedev->trans_rollback();
}
log_message('error', 'Error in delete_uprequest: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Count pending upload requests
*
* @param string $type The type of upload ('dicom' or 'metadata')
* @return int|bool Number of pending requests or FALSE on error
*/
public function count_pending_requests($type = 'dicom') {
try {
$status_field = ($type == 'dicom') ? 'GdcUpreq_DicomUpStatus' : 'GdcUpreq_MetadataUpStatus';
$sql = "SELECT COUNT(*) as total FROM {$this->table}
WHERE {$status_field} = 0 AND GdcUpreq_IsActive = 'Y'";
$query = $this->db_onedev->query($sql);
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
$result = $query->row_array();
return (int)$result['total'];
} catch (Exception $e) {
log_message('error', 'Error in count_pending_requests: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
/**
* Get failed uploads for retry
*
* @param string $type The type of upload ('dicom' or 'metadata')
* @param int $max_retries Maximum number of retries allowed
* @return array|bool Array of failed uploads eligible for retry or FALSE on error
*/
public function get_failed_for_retry($type = 'dicom', $max_retries = 3) {
try {
$status_field = ($type == 'dicom') ? 'GdcUpreq_DicomUpStatus' : 'GdcUpreq_MetadataUpStatus';
$retry_field = ($type == 'dicom') ? 'GdcUpreq_DicomUpRetry' : 'GdcUpreq_MetadataUpRetry';
$sql = "SELECT * FROM {$this->table}
WHERE {$status_field} = 3
AND {$retry_field} < ?
AND GdcUpreq_IsActive = 'Y'";
$query = $this->db_onedev->query($sql, array($max_retries));
// Check for query errors
if (!$query) {
throw new Exception("Database error: " . json_encode($this->db_onedev->error()));
}
return $query->result_array();
} catch (Exception $e) {
log_message('error', 'Error in get_failed_for_retry: ' . $e->getMessage());
$this->sys_error($e->getMessage());
return FALSE;
}
}
}