db_smartone = $this->load->database("onedev", true); } public function search() { $prm = $this->sys_input; $max_rst = 50; // Batasi hasil untuk performa $sdate = $prm["start_date"]; $search = $prm["search"]; $page = $prm['page']; $group_id = 0; if (isset($prm['group_id'])) $group_id = $prm['group_id']; $company_id = 0; $q_company = ""; if (isset($prm['company_id'])) { $company_id = $prm['company_id']; if ($company_id > 0 ) { $q_company = " AND oh.T_OrderHeaderM_CompanyID = $company_id "; } } $q_search = ""; $search_params = []; if (!empty($search)) { $q_search = " AND ( p.M_PatientName LIKE ? OR oh.T_OrderHeaderLabNumber LIKE ? OR oha.T_OrderHeaderAddOnLabNumberOrigin LIKE ? OR oh.T_OrderHeaderLabNumberExt LIKE ? )"; $search_like = "%{$search}%"; $search_params = [$search_like, $search_like, $search_like, $search_like]; } if ($page == null) $page = 1; $offset = ($page - 1) * $max_rst; $q_group = ""; $group_params = []; if ($group_id != 0) { $q_group = " AND EXISTS ( SELECT 1 FROM t_worklistdetailv2 wd WHERE wd.T_WorklistDetailT_WorklistID = ? AND wd.T_WorklistDetailNat_TestID = t.T_TestNat_TestID LIMIT 1 )"; $group_params[] = $group_id; } // Optimasi: Pisahkan query menjadi 2 tahap // Tahap 1: Ambil ID saja dengan filter yang ketat $id_sql = " SELECT DISTINCT oh.T_OrderHeaderID FROM t_orderheader oh INNER JOIN t_orderheaderaddon oha ON oha.T_OrderHeaderAddOnT_OrderHeaderID = oh.T_OrderHeaderID INNER JOIN m_patient p ON oh.T_OrderHeaderM_PatientID = p.M_PatientID LEFT JOIN t_orderpromise op ON op.T_OrderPromiseT_OrderHeaderID = oh.T_OrderHeaderID AND op.T_OrderPromiseIsActive = 'Y' " . ($group_id != 0 ? " INNER JOIN t_orderdetail od ON od.T_OrderDetailT_OrderHeaderID = oh.T_OrderHeaderID AND od.T_OrderDetailIsActive = 'Y' INNER JOIN t_test t ON od.T_OrderDetailT_TestID = t.T_TestID INNER JOIN group_resultdetail grd ON grd.Group_ResultDetailT_TestID = t.T_TestID AND grd.Group_ResultDetailIsActive = 'Y' INNER JOIN group_result gr ON gr.Group_ResultID = grd.Group_ResultDetailGroup_ResultID AND gr.Group_ResultResumeMcu = 'LAB' " : "") . " WHERE oh.T_OrderHeaderIsActive = 'Y' AND oha.T_OrderHeaderAddOnLabNumberOrigin IS NULL AND oha.T_OrderHeaderAddOnFOVerification = 'Y' AND ( (op.T_OrderPromiseIsActive = 'Y' AND DATE(op.T_OrderPromiseDateTime) = ?) OR DATE(oh.T_OrderHeaderDate) = ? ) {$q_company} {$q_search} {$q_group} ORDER BY oh.T_OrderHeaderIsCito DESC, oh.T_OrderHeaderLabNumber LIMIT {$max_rst} OFFSET {$offset} "; $params = [$sdate, $sdate]; $params = array_merge($params, $group_params); $params = array_merge($params, $search_params); $id_query = $this->db_smartone->query($id_sql, $params); if (!$id_query || $id_query->num_rows() == 0) { $this->sys_ok(array("total" => 0, "total_page" => 0, "cur_page" => $page, "records" => [], "total_display" => 0)); return; } // Ambil ID yang sudah difilter $order_ids = array(); foreach($id_query->result_array() as $row) { $order_ids[] = $row['T_OrderHeaderID']; } $order_ids_str = implode(',', $order_ids); // Tahap 2: Ambil detail data hanya untuk ID yang sudah difilter $sql = " SELECT oh.T_OrderHeaderID, oh.T_OrderHeaderLabNumber, oh.T_OrderHeaderDate, COALESCE(oha.T_OrderHeaderAddOnLabNumberOrigin, oh.T_OrderHeaderLabNumberExt) as T_OrderHeaderLabNumberExt, p.M_PatientID, p.M_PatientNoReg, fn_global_patient_name(p.M_PatientID) as M_PatientName, p.M_PatientDOB, oh.T_OrderHeaderM_PatientAge, p.M_PatientHP, s.M_SexName, p.M_PatientNote, da.M_DoctorID as doctor_pj_id, fn_global_doctor_name(da.M_DoctorID) as doctor_pj_name, db.M_DoctorID as doctor_sender_id, fn_global_doctor_name(db.M_DoctorID) as doctor_sender_name, mou.M_MouID, mou.M_MouName, c.M_CompanyID, c.M_CompanyName, oh.T_OrderHeaderFoNote, oh.T_OrderHeaderSamplingNote, COALESCE(ohl.T_OrderHeaderLangResultNote, oh.T_OrderHeaderResultNote) as T_OrderHeaderResultNote, COALESCE( CASE WHEN la.Nat_LangCode <> 'ID' THEN la.Nat_LangID END, CASE WHEN lb.Nat_LangCode <> 'ID' THEN lb.Nat_LangID END, la.Nat_LangID ) as M_LangID, COALESCE( CASE WHEN la.Nat_LangCode <> 'ID' THEN la.Nat_LangCode END, CASE WHEN lb.Nat_LangCode <> 'ID' THEN lb.Nat_LangCode END, la.Nat_LangCode ) as M_LangCode, COALESCE( CASE WHEN la.Nat_LangCode <> 'ID' THEN la.Nat_LangName END, CASE WHEN lb.Nat_LangCode <> 'ID' THEN lb.Nat_LangName END, la.Nat_LangName ) as M_LangName, COALESCE( CASE WHEN la.Nat_LangCode <> 'ID' THEN oh.T_OrderHeaderLangIsSI END, CASE WHEN lb.Nat_LangCode <> 'ID' THEN oha.T_OrderHeaderAddOnSecondLangIsSI END, oh.T_OrderHeaderLangIsSI ) as langissi, COALESCE( CASE WHEN la.Nat_LangCode <> 'ID' THEN la.Nat_LangID END, CASE WHEN lb.Nat_LangCode <> 'ID' THEN lb.Nat_LangID END, la.Nat_LangID ) as langid, COALESCE( CASE WHEN la.Nat_LangCode <> 'ID' THEN la.Nat_LangCode END, CASE WHEN lb.Nat_LangCode <> 'ID' THEN lb.Nat_LangCode END, la.Nat_LangCode ) as langcode, oh.T_OrderHeaderIsCito, fn_global_delivery_items(oh.T_OrderHeaderID) as delivery, fn_process_history(oh.T_OrderHeaderID) as is_history, oha.T_OrderHeaderAddOnVerificationDone, oha.T_OrderHeaderAddOnValidationDone, b.M_BranchCode, CONCAT('[', GROUP_CONCAT( DISTINCT CONCAT('\"', op.T_OrderPromiseDateTime, '\"') SEPARATOR ',' ), ']') as order_promise FROM t_orderheader oh INNER JOIN t_orderheaderaddon oha ON oha.T_OrderHeaderAddOnT_OrderHeaderID = oh.T_OrderHeaderID AND T_OrderHeaderAddOnSecondM_LangID <> 1 INNER JOIN m_patient p ON oh.T_OrderHeaderM_PatientID = p.M_PatientID INNER JOIN m_sex s ON p.M_PatientM_SexID = s.M_SexID INNER JOIN m_company c ON oh.T_OrderHeaderM_CompanyID = c.M_CompanyID INNER JOIN m_mou mou ON oh.T_OrderHeaderM_MouID = mou.M_MouID LEFT JOIN m_doctor da ON oh.T_OrderHeaderPJM_DoctorID = da.M_DoctorID INNER JOIN m_doctor db ON oh.T_OrderHeaderSenderM_DoctorID = db.M_DoctorID INNER JOIN m_branch b ON b.M_BranchIsDefault = 'Y' AND b.M_BranchIsActive = 'Y' INNER JOIN nat_lang la ON oh.T_OrderHeaderM_LangID = la.Nat_LangID LEFT JOIN nat_lang lb ON oha.T_OrderHeaderAddOnSecondM_LangID = lb.Nat_LangID LEFT JOIN t_orderheaderlang ohl ON ohl.T_OrderHeaderLangT_OrderHeaderID = oh.T_OrderHeaderID LEFT JOIN t_orderpromise op ON op.T_OrderPromiseT_OrderHeaderID = oh.T_OrderHeaderID AND op.T_OrderPromiseIsActive = 'Y' WHERE oh.T_OrderHeaderID IN ({$order_ids_str}) GROUP BY oh.T_OrderHeaderID ORDER BY FIELD(oh.T_OrderHeaderID, {$order_ids_str}) "; $query = $this->db_smartone->query($sql); // Count query yang lebih simple $count_sql = " SELECT COUNT(DISTINCT oh.T_OrderHeaderID) as total FROM t_orderheader oh INNER JOIN t_orderheaderaddon oha ON oha.T_OrderHeaderAddOnT_OrderHeaderID = oh.T_OrderHeaderID AND T_OrderHeaderAddOnSecondM_LangID <> 1 INNER JOIN m_patient p ON oh.T_OrderHeaderM_PatientID = p.M_PatientID LEFT JOIN t_orderpromise op ON op.T_OrderPromiseT_OrderHeaderID = oh.T_OrderHeaderID AND op.T_OrderPromiseIsActive = 'Y' " . ($group_id != 0 ? " INNER JOIN t_orderdetail od ON od.T_OrderDetailT_OrderHeaderID = oh.T_OrderHeaderID AND od.T_OrderDetailIsActive = 'Y' INNER JOIN t_test t ON od.T_OrderDetailT_TestID = t.T_TestID " : "") . " WHERE oh.T_OrderHeaderIsActive = 'Y' AND oha.T_OrderHeaderAddOnLabNumberOrigin IS NULL AND oha.T_OrderHeaderAddOnFOVerification = 'Y' AND ( (op.T_OrderPromiseIsActive = 'Y' AND DATE(op.T_OrderPromiseDateTime) = ?) OR DATE(oh.T_OrderHeaderDate) = ? ) {$q_company} {$q_search} {$q_group} "; $count_params = [$sdate, $sdate]; $count_params = array_merge($count_params, $group_params); $count_params = array_merge($count_params, $search_params); $count_query = $this->db_smartone->query($count_sql, $count_params); $tot_count = $count_query ? $count_query->row()->total : 0; if ($query) { $rows = $query->result_array(); foreach ($rows as $k => $v) { $lang[] = ["id"=>$v['langid'], "code"=>$v['langcode'], "is_si"=>$v['langissi']]; $rows[$k]['lang'] = $lang; $rows[$k]['delivery'] = JSON_DECODE($v['delivery']); $rows[$k]['order_promise'] = JSON_DECODE($v['order_promise']); if(is_array($rows[$k]['order_promise'])) { foreach($rows[$k]['order_promise'] as $l => $w) $rows[$k]['order_promise'][$l] = date('d-m-Y H:i', strtotime($w)); } } $result = array("total" => $tot_count, "total_page" => ceil($tot_count/$max_rst), "cur_page" => $page, "records" => $rows, "total_display" => sizeof($rows), "q" => $this->db_smartone->last_query()); $this->sys_ok($result); } else { $this->sys_error_db("worklist rows", $this->db_smartone); exit; } } public function history() { $prm = $this->sys_input; // QUERY TOTAL $sql = "CALL sp_process_result_history(?)"; $query = $this->db_smartone->query($sql, [$prm['order_id']]); if ($query) { $row = $query->row(); $history = json_decode($row->rst); $this->sys_ok($history); } else { $this->sys_error_db("RESULT HISTORY", $this->db_smartone); exit; } } public function save_note() { $prm = $this->sys_input; $sql = "INSERT INTO t_orderheaderlang (T_OrderHeaderLangT_OrderHeaderID, T_OrderHeaderLangResultNote, T_OrderHeaderLangResultNoteM_UserID, T_OrderHeaderLangCreated, T_OrderHeaderLangLastUpdated, T_OrderHeaderLangUserID) VALUES (?,?,?,now(),now(),?) ON DUPLICATE KEY UPDATE T_OrderHeaderLangResultNote = ?, T_OrderHeaderLangResultNoteM_UserID = ?, T_OrderHeaderLangLastUpdated = now(), T_OrderHeaderLangUserID = ?"; $query = $this->db_smartone->query($sql,[$prm['order_id'],$prm['note'], $this->sys_user['M_UserID'],$this->sys_user['M_UserID'],$prm['note'], $this->sys_user['M_UserID'], $this->sys_user['M_UserID']]); if ($query) { $this->sys_ok($prm['order_id']); exit; } $this->sys_error_db("RESULT NOTE", $this->db_smartone); } public function info_req() { $prm = $this->sys_input; $sql = "CALL sp_process_result_reqs(?)"; $query = $this->db_smartone->query($sql, [$prm['order_id']]); if ($query) { $row = $query->row(); $s_data = $row->data; $s_data = str_replace("\n"," ",$s_data); $this->sys_ok(json_decode($s_data)); exit; } $this->sys_error_db("RESULT REQ", $this->db_smartone); } }