FHM08062601IBL - ganti fn_sampling_get_normal dan sp_sampling_check/fix_normal dengan PHP library Ibl_sampling_normal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -69,13 +69,8 @@ class Re_px extends MY_Controller
|
||||
return array(0,"");
|
||||
}
|
||||
function get_normal_value($methodeID, $natTestID, $sexID, $ageInDay ) {
|
||||
$sql = "select fn_sampling_get_normal($methodeID, $natTestID, $sexID, $ageInDay) as normalValueID";
|
||||
$qry = $this->db->query($sql);
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) return $rows[0]["normalValueID"];
|
||||
}
|
||||
return 0;
|
||||
$this->load->library('ibl_sampling_normal');
|
||||
return $this->ibl_sampling_normal->get_normal_value_id($methodeID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
function fn_fix_normal($order_id) {
|
||||
|
||||
|
||||
@@ -69,13 +69,8 @@ class Re_px extends MY_Controller
|
||||
return array(0,"");
|
||||
}
|
||||
function get_normal_value($methodeID, $natTestID, $sexID, $ageInDay ) {
|
||||
$sql = "select fn_sampling_get_normal($methodeID, $natTestID, $sexID, $ageInDay) as normalValueID";
|
||||
$qry = $this->db->query($sql);
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) return $rows[0]["normalValueID"];
|
||||
}
|
||||
return 0;
|
||||
$this->load->library('ibl_sampling_normal');
|
||||
return $this->ibl_sampling_normal->get_normal_value_id($methodeID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
function fn_fix_normal($order_id) {
|
||||
$sql = "select
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -69,13 +69,8 @@ class Re_px extends MY_Controller
|
||||
return array(0,"");
|
||||
}
|
||||
function get_normal_value($methodeID, $natTestID, $sexID, $ageInDay ) {
|
||||
$sql = "select fn_sampling_get_normal($methodeID, $natTestID, $sexID, $ageInDay) as normalValueID";
|
||||
$qry = $this->db->query($sql);
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) return $rows[0]["normalValueID"];
|
||||
}
|
||||
return 0;
|
||||
$this->load->library('ibl_sampling_normal');
|
||||
return $this->ibl_sampling_normal->get_normal_value_id($methodeID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
function fn_fix_normal($order_id) {
|
||||
$sql = "select
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
546
application/libraries/Ibl_sampling_normal.php
Normal file
546
application/libraries/Ibl_sampling_normal.php
Normal file
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Pengganti fn_sampling_get_normal, sp_sampling_check_normal_setting,
|
||||
* dan sp_sampling_fix_normal_by_orderdetail (MySQL).
|
||||
*
|
||||
* Alasan: SP/fungsi MySQL membaca M_PatientDOB langsung dari m_patient,
|
||||
* yang NULL setelah enkripsi PDP. Library ini decrypt M_PatientDOB_enc
|
||||
* di PHP sebelum menghitung usia.
|
||||
*/
|
||||
class Ibl_sampling_normal
|
||||
{
|
||||
private $db;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$CI = &get_instance();
|
||||
$this->db = $CI->load->database('onedev', true);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Cari Nat_NormalValueID sesuai methode, test, sex, dan umur (dalam hari).
|
||||
* Urutan prioritas:
|
||||
* Type 1 — sex + age range
|
||||
* Type 2 — age range saja
|
||||
* Type 3 — sex saja
|
||||
* Type 4 — fallback
|
||||
*/
|
||||
public function get_normal_value_id($methodeID, $natTestID, $sexID, $ageInDay)
|
||||
{
|
||||
$methodeID = intval($methodeID);
|
||||
$natTestID = intval($natTestID);
|
||||
$sexID = intval($sexID);
|
||||
$ageInDay = intval($ageInDay);
|
||||
|
||||
$min_days = $this->_age_sql('Nat_NormalValueMinAge');
|
||||
$max_days = $this->_age_sql('Nat_NormalValueMaxAge');
|
||||
|
||||
$age_filter = "
|
||||
AND (
|
||||
(Nat_NormalValueMinAgeInclusive = 'Y' AND ($min_days) <= $ageInDay)
|
||||
OR (Nat_NormalValueMinAgeInclusive = 'N' AND ($min_days) < $ageInDay)
|
||||
)
|
||||
AND (
|
||||
(Nat_NormalValueMaxAgeInclusive = 'Y' AND ($max_days) >= $ageInDay)
|
||||
OR (Nat_NormalValueMaxAgeInclusive = 'N' AND ($max_days) > $ageInDay)
|
||||
)";
|
||||
|
||||
$base = "FROM nat_normalvalue
|
||||
WHERE (Nat_NormalValueValidDate IS NULL OR Nat_NormalValueValidDate < NOW())
|
||||
AND Nat_NormalValueIsActive = 'Y'
|
||||
AND Nat_NormalValueIsAbnormal = 'N'
|
||||
AND Nat_NormalValueNat_MethodeID = $methodeID
|
||||
AND Nat_NormalValueNat_TestID = $natTestID
|
||||
AND Nat_NormalValueNat_FlagID = 1";
|
||||
|
||||
$id = $this->_query_one("SELECT Nat_NormalValueID $base
|
||||
AND Nat_NormalValueNat_NormalValueTypeID = 1
|
||||
AND Nat_NormalValueNat_SexID = $sexID
|
||||
$age_filter LIMIT 1");
|
||||
if ($id) return $id;
|
||||
|
||||
$id = $this->_query_one("SELECT Nat_NormalValueID $base
|
||||
AND Nat_NormalValueNat_NormalValueTypeID = 2
|
||||
$age_filter LIMIT 1");
|
||||
if ($id) return $id;
|
||||
|
||||
$id = $this->_query_one("SELECT Nat_NormalValueID $base
|
||||
AND Nat_NormalValueNat_NormalValueTypeID = 3
|
||||
AND Nat_NormalValueNat_SexID = $sexID
|
||||
LIMIT 1");
|
||||
if ($id) return $id;
|
||||
|
||||
$id = $this->_query_one("SELECT Nat_NormalValueID $base
|
||||
AND Nat_NormalValueNat_NormalValueTypeID = 4
|
||||
LIMIT 1");
|
||||
if ($id) return $id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pengganti sp_sampling_check_normal_setting.
|
||||
* Mengembalikan array compat dengan call_multi_result_procedure():
|
||||
* ok, message, result_sets[0]=summary, [1]=checks, [2]=branches, [3]=candidates
|
||||
*/
|
||||
public function check_setting_by_order_detail($orderDetailID)
|
||||
{
|
||||
$orderDetailID = intval($orderDetailID);
|
||||
$data = $this->_load_order_detail_data($orderDetailID);
|
||||
if ($data === null) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'message' => "T_OrderDetailID {$orderDetailID} tidak ditemukan atau tidak aktif",
|
||||
'result_sets' => [],
|
||||
];
|
||||
}
|
||||
|
||||
list($sexID, $dobStr, $orderDate, $ageInDay,
|
||||
$orderHeaderID, $patientID, $natTestID,
|
||||
$row) = $data;
|
||||
|
||||
$methods = $this->_resolve_method_sources($natTestID);
|
||||
list($selID, $selName, $selSource) = $this->_pick_method($methods);
|
||||
|
||||
$normalValueID = 0;
|
||||
if ($selID > 0 && $natTestID > 0 && $sexID > 0 && $ageInDay !== null) {
|
||||
$normalValueID = $this->get_normal_value_id($selID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
|
||||
$summary = [[
|
||||
'T_OrderDetailID' => $orderDetailID,
|
||||
'T_OrderHeaderID' => $orderHeaderID,
|
||||
'M_PatientID' => $patientID,
|
||||
'M_PatientM_SexID' => $sexID ?: null,
|
||||
'M_PatientDOB' => $dobStr ?: null,
|
||||
'T_OrderHeaderDate' => $row['order_date'],
|
||||
'AgeInDay' => $ageInDay,
|
||||
'T_TestID' => intval($row['t_test_id']),
|
||||
'T_TestName' => $row['t_test_name'],
|
||||
'Nat_TestID' => $natTestID ?: null,
|
||||
'Nat_TestCode' => $row['nat_test_code'],
|
||||
'Nat_TestName' => $row['nat_test_name'],
|
||||
'T_OrderDetailNat_MethodeID'=> intval($row['order_detail_methode_id']),
|
||||
'MethodeIDFromPriority' => $methods['priority_id'] ?: null,
|
||||
'MethodeNameFromPriority' => $methods['priority_name'],
|
||||
'MethodeIDFromInstrument' => $methods['instrument_id'] ?: null,
|
||||
'MethodeNameFromInstrument' => $methods['instrument_name'],
|
||||
'MethodeIDFromNormalValue' => $methods['normalvalue_id'] ?: null,
|
||||
'MethodeNameFromNormalValue'=> $methods['normalvalue_name'],
|
||||
'SelectedMethodeID' => $selID,
|
||||
'SelectedMethodeName' => $selName,
|
||||
'SelectedMethodeSource' => $selSource,
|
||||
'FnSamplingGetNormalResult' => $normalValueID,
|
||||
]];
|
||||
|
||||
$nvCount = 0;
|
||||
if ($natTestID > 0) {
|
||||
$r = $this->db->query(
|
||||
"SELECT COUNT(*) AS cnt FROM nat_normalvalue
|
||||
WHERE Nat_NormalValueNat_TestID = ?
|
||||
AND Nat_NormalValueNat_MethodeID = ?
|
||||
AND Nat_NormalValueIsActive = 'Y'
|
||||
AND Nat_NormalValueIsAbnormal = 'N'",
|
||||
[$natTestID, $selID ?: 0]
|
||||
)->row_array();
|
||||
$nvCount = intval($r['cnt'] ?? 0);
|
||||
}
|
||||
|
||||
$checks = [
|
||||
$this->_chk('ORDER_DETAIL_ACTIVE', true, (string) $orderDetailID, 't_orderdetail aktif harus ditemukan'),
|
||||
$this->_chk('PATIENT_SEX', $sexID > 0, (string) ($sexID ?: 'NULL'), 'Dipakai pada type 1 dan type 3'),
|
||||
$this->_chk('PATIENT_DOB', $dobStr !== '', ($dobStr ?: 'NULL'), 'DOB dipakai untuk hitung AgeInDay'),
|
||||
$this->_chk('ORDER_DATE', !empty($row['order_date']), ($row['order_date'] ?: 'NULL'), 'Tanggal order dipakai untuk hitung AgeInDay'),
|
||||
$this->_chk('AGE_IN_DAY', $ageInDay !== null, ($ageInDay !== null ? (string) $ageInDay : 'NULL'), 'Dipakai pada type 1 dan type 2'),
|
||||
$this->_chk('NAT_TEST', $natTestID > 0, (string) ($natTestID ?: 'NULL'), 'Harus ada mapping T_TestNat_TestID'),
|
||||
$this->_chk('METHOD_PRIORITY', $methods['priority_id'] > 0, (string) ($methods['priority_id'] ?: 'NULL'), 'Sumber metode prioritas pertama'),
|
||||
$this->_chk('METHOD_INSTRUMENT', $methods['instrument_id'] > 0, (string) ($methods['instrument_id'] ?: 'NULL'), 'Fallback metode kedua'),
|
||||
$this->_chk('METHOD_NORMALVALUE', $methods['normalvalue_id'] > 0, (string) ($methods['normalvalue_id'] ?: 'NULL'), 'Fallback metode ketiga'),
|
||||
$this->_chk('SELECTED_METHOD', $selID > 0, (string) ($selID ?: 'NULL'), ($selSource ?: 'Tidak ada metode yang bisa dipakai')),
|
||||
$this->_chk('NORMALVALUE_TEST_METHOD_ACTIVE', $nvCount > 0, (string) $nvCount, 'Jumlah nat_normalvalue aktif non-abnormal untuk test + metode terpilih'),
|
||||
['check_name' => 'FN_RESULT', 'check_status' => ($normalValueID > 0 ? 'OK' : 'NOT_FOUND'), 'check_value' => (string) $normalValueID, 'check_note' => 'Hasil akhir fn_sampling_get_normal'],
|
||||
];
|
||||
|
||||
$branches = $selID > 0
|
||||
? $this->_query_branches($selID, $natTestID, $sexID, $ageInDay)
|
||||
: [['branch_name' => 'NO_SELECTED_METHOD', 'matched_count' => 0, 'first_normalvalue_id' => null]];
|
||||
$candidates = $natTestID > 0 ? $this->_query_candidates($selID, $natTestID, $sexID, $ageInDay) : [];
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'message' => '',
|
||||
'result_sets' => [$summary, $checks, $branches, $candidates],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pengganti sp_sampling_fix_normal_by_orderdetail.
|
||||
* Mengembalikan array compat dengan call_multi_result_procedure():
|
||||
* ok, message, result_sets[0]=result_row, [1]=order_detail_row
|
||||
*/
|
||||
public function fix_by_order_detail($orderDetailID)
|
||||
{
|
||||
$orderDetailID = intval($orderDetailID);
|
||||
$data = $this->_load_order_detail_data($orderDetailID);
|
||||
if ($data === null) {
|
||||
$errRow = [[
|
||||
'status' => 'ERR',
|
||||
'message' => "T_OrderDetailID {$orderDetailID} tidak ditemukan atau tidak aktif",
|
||||
'selected_methode_id' => null,
|
||||
'selected_methode_name'=> null,
|
||||
'selected_methode_source' => null,
|
||||
'nat_normalvalue_id' => null,
|
||||
'updated_rows' => 0,
|
||||
]];
|
||||
return ['ok' => true, 'message' => '', 'result_sets' => [$errRow, []]];
|
||||
}
|
||||
|
||||
list($sexID, $dobStr, $orderDate, $ageInDay,
|
||||
$orderHeaderID, $patientID, $natTestID,
|
||||
$row) = $data;
|
||||
|
||||
$methods = $this->_resolve_method_sources($natTestID);
|
||||
list($selID, $selName, $selSource) = $this->_pick_method($methods);
|
||||
|
||||
$normalValueID = 0;
|
||||
if ($selID > 0 && $natTestID > 0 && $sexID > 0 && $ageInDay !== null) {
|
||||
$normalValueID = $this->get_normal_value_id($selID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
|
||||
if ($normalValueID > 0) {
|
||||
$this->db->query(
|
||||
"UPDATE t_orderdetail od
|
||||
JOIN nat_normalvalue nn ON nn.Nat_NormalValueID = ?
|
||||
SET od.T_OrderDetailNat_NormalValueID = nn.Nat_NormalValueID,
|
||||
od.T_OrderDetailNormalValueNote = nn.Nat_NormalValueNote,
|
||||
od.T_OrderDetailNormalValueDescription = nn.Nat_NormalValueDescription,
|
||||
od.T_OrderDetailMinValue = nn.Nat_NormalValueMinValue,
|
||||
od.T_OrderDetailMaxValue = nn.Nat_NormalValueMaxValue,
|
||||
od.T_OrderDetailMinValueInclusive = nn.Nat_NormalValueMinValueInclusive,
|
||||
od.T_OrderDetailMaxValueInclusive = nn.Nat_NormalValueMaxValueInclusive,
|
||||
od.T_OrderDetailNat_MethodeID = ?,
|
||||
od.T_OrderdetailNat_MethodeName = ?
|
||||
WHERE od.T_OrderDetailID = ?
|
||||
AND od.T_OrderDetailIsActive = 'Y'",
|
||||
[$normalValueID, $selID, $selName, $orderDetailID]
|
||||
);
|
||||
$updatedRows = $this->db->affected_rows();
|
||||
$resultRow = [[
|
||||
'status' => 'OK',
|
||||
'message' => "Normal value berhasil diupdate untuk T_OrderDetailID {$orderDetailID}",
|
||||
'selected_methode_id' => $selID,
|
||||
'selected_methode_name'=> $selName,
|
||||
'selected_methode_source' => $selSource,
|
||||
'nat_normalvalue_id' => $normalValueID,
|
||||
'updated_rows' => $updatedRows,
|
||||
]];
|
||||
} else {
|
||||
$resultRow = [[
|
||||
'status' => 'NOT_FOUND',
|
||||
'message' => "Normal value tidak ditemukan untuk T_OrderDetailID {$orderDetailID}",
|
||||
'selected_methode_id' => $selID,
|
||||
'selected_methode_name'=> $selName,
|
||||
'selected_methode_source' => $selSource,
|
||||
'nat_normalvalue_id' => $normalValueID,
|
||||
'updated_rows' => 0,
|
||||
]];
|
||||
}
|
||||
|
||||
$odRow = $this->db->query(
|
||||
"SELECT T_OrderDetailID, T_OrderDetailNat_NormalValueID, T_OrderDetailNat_MethodeID,
|
||||
T_OrderdetailNat_MethodeName, T_OrderDetailNormalValueDescription,
|
||||
T_OrderDetailMinValue, T_OrderDetailMaxValue,
|
||||
T_OrderDetailMinValueInclusive, T_OrderDetailMaxValueInclusive
|
||||
FROM t_orderdetail WHERE T_OrderDetailID = ? LIMIT 1",
|
||||
[$orderDetailID]
|
||||
)->result_array();
|
||||
|
||||
return ['ok' => true, 'message' => '', 'result_sets' => [$resultRow, $odRow]];
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private helpers
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Inline pengganti fn_normal_get_age: konversi kolom usia ke hari di SQL. */
|
||||
private function _age_sql($col)
|
||||
{
|
||||
return "CASE Nat_NormalValueAgeUnit
|
||||
WHEN 'HARI' THEN {$col}
|
||||
WHEN 'BULAN' THEN {$col} * 30
|
||||
WHEN 'TAHUN' THEN {$col} * 365
|
||||
ELSE {$col}
|
||||
END";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ambil data dasar order detail termasuk DOB terenkripsi.
|
||||
* Return [sexID, dobStr, orderDate, ageInDay, orderHeaderID, patientID, natTestID, $row]
|
||||
* atau null jika tidak ditemukan.
|
||||
*/
|
||||
private function _load_order_detail_data($orderDetailID)
|
||||
{
|
||||
$row = $this->db->query(
|
||||
"SELECT
|
||||
od.T_OrderDetailT_OrderHeaderID AS order_header_id,
|
||||
oh.T_OrderHeaderM_PatientID AS patient_id,
|
||||
p.M_PatientM_SexID AS sex_id,
|
||||
p.M_PatientDOB_enc,
|
||||
p.M_PatientDOB,
|
||||
DATE(oh.T_OrderHeaderDate) AS order_date,
|
||||
od.T_OrderDetailT_TestID AS t_test_id,
|
||||
tt.T_TestName AS t_test_name,
|
||||
tt.T_TestNat_TestID AS nat_test_id,
|
||||
nt.Nat_TestCode AS nat_test_code,
|
||||
nt.Nat_TestName AS nat_test_name,
|
||||
od.T_OrderDetailNat_MethodeID AS order_detail_methode_id
|
||||
FROM t_orderdetail od
|
||||
JOIN t_orderheader oh ON oh.T_OrderHeaderID = od.T_OrderDetailT_OrderHeaderID
|
||||
JOIN m_patient p ON p.M_PatientID = oh.T_OrderHeaderM_PatientID
|
||||
LEFT JOIN t_test tt ON tt.T_TestID = od.T_OrderDetailT_TestID
|
||||
LEFT JOIN nat_test nt ON nt.Nat_TestID = tt.T_TestNat_TestID
|
||||
WHERE od.T_OrderDetailID = ?
|
||||
AND od.T_OrderDetailIsActive = 'Y'
|
||||
LIMIT 1",
|
||||
[$orderDetailID]
|
||||
)->row_array();
|
||||
|
||||
if (!$row) return null;
|
||||
|
||||
$dobStr = '';
|
||||
if (!empty($row['M_PatientDOB_enc'])) {
|
||||
$CI = &get_instance();
|
||||
$CI->load->library('ibl_encryptor');
|
||||
$dobStr = (string) ($CI->ibl_encryptor->decrypt($row['M_PatientDOB_enc']) ?? '');
|
||||
}
|
||||
if ($dobStr === '' && !empty($row['M_PatientDOB'])) {
|
||||
$dobStr = $row['M_PatientDOB'];
|
||||
}
|
||||
|
||||
$ageInDay = null;
|
||||
if ($dobStr !== '' && !empty($row['order_date'])) {
|
||||
try {
|
||||
$dob = new DateTime($dobStr);
|
||||
$oDate = new DateTime($row['order_date']);
|
||||
$ageInDay = (int) $oDate->diff($dob)->days;
|
||||
} catch (Exception $e) {}
|
||||
}
|
||||
|
||||
return [
|
||||
intval($row['sex_id']),
|
||||
$dobStr,
|
||||
$row['order_date'],
|
||||
$ageInDay,
|
||||
intval($row['order_header_id']),
|
||||
intval($row['patient_id']),
|
||||
intval($row['nat_test_id']),
|
||||
$row,
|
||||
];
|
||||
}
|
||||
|
||||
/** Resolusi metode dari 3 sumber: priority → instrument → normalvalue. */
|
||||
private function _resolve_method_sources($natTestID)
|
||||
{
|
||||
$r = $this->db->query(
|
||||
"SELECT mp.M_MethodePriorityNat_MethodeID, nm.Nat_MethodeName
|
||||
FROM m_methode_priority mp
|
||||
JOIN nat_methode nm ON nm.Nat_MethodeID = mp.M_MethodePriorityNat_MethodeID AND nm.Nat_MethodeIsActive = 'Y'
|
||||
JOIN m_instrumentmethode im ON im.M_InstrumentMethodeNat_MethodeID = nm.Nat_MethodeID AND im.M_InstrumentMethodeIsActive = 'Y'
|
||||
JOIN nat_instrument ni ON ni.Nat_InstrumentID = im.M_InstrumentMethodeNat_InstrumentID AND ni.Nat_InstrumentIsActive = 'Y'
|
||||
WHERE mp.M_MethodePriorityIsActive = 'Y'
|
||||
AND mp.M_MethodePriorityNat_TestID = ?
|
||||
AND mp.M_MethodePriorityM_DayOfWeekID = DAYOFWEEK(NOW())
|
||||
ORDER BY mp.M_MethodePriorityNumber DESC LIMIT 1",
|
||||
[$natTestID]
|
||||
)->row_array();
|
||||
$priorityID = intval($r['M_MethodePriorityNat_MethodeID'] ?? 0);
|
||||
$priorityName = $r['Nat_MethodeName'] ?? null;
|
||||
|
||||
$r = $this->db->query(
|
||||
"SELECT im.M_InstrumentMethodeNat_MethodeID, nm.Nat_MethodeName
|
||||
FROM m_instrumentmethode im
|
||||
JOIN nat_methode nm ON nm.Nat_MethodeID = im.M_InstrumentMethodeNat_MethodeID AND nm.Nat_MethodeIsActive = 'Y'
|
||||
JOIN nat_instrument ni ON ni.Nat_InstrumentID = im.M_InstrumentMethodeNat_InstrumentID AND ni.Nat_InstrumentIsActive = 'Y'
|
||||
WHERE im.M_InstrumentMethodeNat_TestID = ?
|
||||
AND im.M_InstrumentMethodeIsActive = 'Y'
|
||||
ORDER BY im.M_InstrumentMethodePriority DESC LIMIT 1",
|
||||
[$natTestID]
|
||||
)->row_array();
|
||||
$instrumentID = intval($r['M_InstrumentMethodeNat_MethodeID'] ?? 0);
|
||||
$instrumentName = $r['Nat_MethodeName'] ?? null;
|
||||
|
||||
$r = $this->db->query(
|
||||
"SELECT nn.Nat_NormalValueNat_MethodeID, nm.Nat_MethodeName
|
||||
FROM nat_normalvalue nn
|
||||
JOIN nat_methode nm ON nm.Nat_MethodeID = nn.Nat_NormalValueNat_MethodeID AND nm.Nat_MethodeIsActive = 'Y'
|
||||
WHERE nn.Nat_NormalValueNat_TestID = ?
|
||||
AND nn.Nat_NormalValueIsActive = 'Y'
|
||||
ORDER BY nn.Nat_NormalValueID LIMIT 1",
|
||||
[$natTestID]
|
||||
)->row_array();
|
||||
$normalID = intval($r['Nat_NormalValueNat_MethodeID'] ?? 0);
|
||||
$normalName = $r['Nat_MethodeName'] ?? null;
|
||||
|
||||
return [
|
||||
'priority_id' => $priorityID,
|
||||
'priority_name' => $priorityName,
|
||||
'instrument_id' => $instrumentID,
|
||||
'instrument_name'=> $instrumentName,
|
||||
'normalvalue_id' => $normalID,
|
||||
'normalvalue_name' => $normalName,
|
||||
];
|
||||
}
|
||||
|
||||
/** Pilih metode terbaik dari hasil _resolve_method_sources(). */
|
||||
private function _pick_method(array $methods)
|
||||
{
|
||||
if ($methods['priority_id'] > 0) {
|
||||
return [$methods['priority_id'], $methods['priority_name'], 'm_methode_priority'];
|
||||
}
|
||||
if ($methods['instrument_id'] > 0) {
|
||||
return [$methods['instrument_id'], $methods['instrument_name'], 'm_instrumentmethode'];
|
||||
}
|
||||
if ($methods['normalvalue_id'] > 0) {
|
||||
return [$methods['normalvalue_id'], $methods['normalvalue_name'], 'nat_normalvalue'];
|
||||
}
|
||||
return [0, null, null];
|
||||
}
|
||||
|
||||
/** Hitung matched_count per TYPE (1..4) untuk branch summary. */
|
||||
private function _query_branches($methodeID, $natTestID, $sexID, $ageInDay)
|
||||
{
|
||||
$min = $this->_age_sql('Nat_NormalValueMinAge');
|
||||
$max = $this->_age_sql('Nat_NormalValueMaxAge');
|
||||
$base = "FROM nat_normalvalue
|
||||
WHERE (Nat_NormalValueValidDate IS NULL OR Nat_NormalValueValidDate < NOW())
|
||||
AND Nat_NormalValueIsActive = 'Y'
|
||||
AND Nat_NormalValueIsAbnormal = 'N'
|
||||
AND Nat_NormalValueNat_FlagID = 1
|
||||
AND Nat_NormalValueNat_MethodeID = $methodeID
|
||||
AND Nat_NormalValueNat_TestID = $natTestID";
|
||||
|
||||
$ageFilter = "
|
||||
AND ((Nat_NormalValueMinAgeInclusive='Y' AND ($min)<=$ageInDay) OR (Nat_NormalValueMinAgeInclusive='N' AND ($min)<$ageInDay))
|
||||
AND ((Nat_NormalValueMaxAgeInclusive='Y' AND ($max)>=$ageInDay) OR (Nat_NormalValueMaxAgeInclusive='N' AND ($max)>$ageInDay))";
|
||||
|
||||
$types = [
|
||||
['TYPE_1', "AND Nat_NormalValueNat_NormalValueTypeID=1 AND Nat_NormalValueNat_SexID=$sexID $ageFilter"],
|
||||
['TYPE_2', "AND Nat_NormalValueNat_NormalValueTypeID=2 $ageFilter"],
|
||||
['TYPE_3', "AND Nat_NormalValueNat_NormalValueTypeID=3 AND Nat_NormalValueNat_SexID=$sexID"],
|
||||
['TYPE_4', "AND Nat_NormalValueNat_NormalValueTypeID=4"],
|
||||
];
|
||||
|
||||
$branches = [];
|
||||
foreach ($types as list($label, $filter)) {
|
||||
$r = $this->db->query("SELECT COUNT(*) AS cnt, MIN(Nat_NormalValueID) AS first_id $base $filter")->row_array();
|
||||
$branches[] = [
|
||||
'branch_name' => $label,
|
||||
'matched_count' => intval($r['cnt'] ?? 0),
|
||||
'first_normalvalue_id'=> $r['first_id'] ?? null,
|
||||
];
|
||||
}
|
||||
return $branches;
|
||||
}
|
||||
|
||||
/** Ambil semua kandidat nat_normalvalue dengan kolom diagnostik match/fail. */
|
||||
private function _query_candidates($methodeID, $natTestID, $sexID, $ageInDay)
|
||||
{
|
||||
if (!$natTestID) return [];
|
||||
|
||||
$min = $this->_age_sql('Nat_NormalValueMinAge');
|
||||
$max = $this->_age_sql('Nat_NormalValueMaxAge');
|
||||
$a = intval($ageInDay);
|
||||
$s = intval($sexID);
|
||||
$m = intval($methodeID);
|
||||
|
||||
$matchMinAge = "(
|
||||
(Nat_NormalValueMinAgeInclusive='Y' AND ($min)<=$a)
|
||||
OR (Nat_NormalValueMinAgeInclusive='N' AND ($min)<$a))";
|
||||
$matchMaxAge = "(
|
||||
(Nat_NormalValueMaxAgeInclusive='Y' AND ($max)>=$a)
|
||||
OR (Nat_NormalValueMaxAgeInclusive='N' AND ($max)>$a))";
|
||||
|
||||
$sql = "SELECT
|
||||
nn.Nat_NormalValueID,
|
||||
nn.Nat_NormalValueNat_TestID,
|
||||
nn.Nat_NormalValueNat_MethodeID,
|
||||
nm.Nat_MethodeName,
|
||||
nn.Nat_NormalValueNat_NormalValueTypeID,
|
||||
nn.Nat_NormalValueNat_SexID,
|
||||
nn.Nat_NormalValueValidDate,
|
||||
nn.Nat_NormalValueMinAge,
|
||||
nn.Nat_NormalValueMaxAge,
|
||||
nn.Nat_NormalValueAgeUnit,
|
||||
nn.Nat_NormalValueMinAgeInclusive,
|
||||
nn.Nat_NormalValueMaxAgeInclusive,
|
||||
($min) AS MinAgeInDay,
|
||||
($max) AS MaxAgeInDay,
|
||||
nn.Nat_NormalValueNat_FlagID,
|
||||
nn.Nat_NormalValueIsAbnormal,
|
||||
nn.Nat_NormalValueIsActive,
|
||||
IF((nn.Nat_NormalValueValidDate IS NULL OR nn.Nat_NormalValueValidDate < NOW()),'Y','N') AS MatchValidDate,
|
||||
IF(nn.Nat_NormalValueIsActive='Y','Y','N') AS MatchActive,
|
||||
IF(nn.Nat_NormalValueIsAbnormal='N','Y','N') AS MatchNotAbnormal,
|
||||
IF(nn.Nat_NormalValueNat_FlagID=1,'Y','N') AS MatchFlag,
|
||||
IF(nn.Nat_NormalValueNat_TestID=$natTestID,'Y','N') AS MatchNatTest,
|
||||
IF($m>0 AND nn.Nat_NormalValueNat_MethodeID=$m,'Y','N') AS MatchSelectedMethod,
|
||||
IF(nn.Nat_NormalValueNat_SexID=$s,'Y','N') AS MatchSex,
|
||||
IF($matchMinAge,'Y','N') AS MatchMinAge,
|
||||
IF($matchMaxAge,'Y','N') AS MatchMaxAge,
|
||||
CASE nn.Nat_NormalValueNat_NormalValueTypeID
|
||||
WHEN 1 THEN IF(nn.Nat_NormalValueNat_SexID=$s AND $matchMinAge AND $matchMaxAge,'Y','N')
|
||||
WHEN 2 THEN IF($matchMinAge AND $matchMaxAge,'Y','N')
|
||||
WHEN 3 THEN IF(nn.Nat_NormalValueNat_SexID=$s,'Y','N')
|
||||
WHEN 4 THEN 'Y'
|
||||
ELSE 'N'
|
||||
END AS MatchTypeRule,
|
||||
CONCAT_WS('; ',
|
||||
IF(NOT(nn.Nat_NormalValueValidDate IS NULL OR nn.Nat_NormalValueValidDate<NOW()),'valid_date_not_passed',NULL),
|
||||
IF(nn.Nat_NormalValueIsActive<>'Y','inactive',NULL),
|
||||
IF(nn.Nat_NormalValueIsAbnormal<>'N','abnormal_row',NULL),
|
||||
IF(nn.Nat_NormalValueNat_FlagID<>1,'flag_not_1',NULL),
|
||||
IF(nn.Nat_NormalValueNat_TestID<>$natTestID,'nat_test_mismatch',NULL),
|
||||
IF($m>0 AND nn.Nat_NormalValueNat_MethodeID<>$m,'methode_mismatch',NULL),
|
||||
IF(nn.Nat_NormalValueNat_NormalValueTypeID IN(1,3) AND nn.Nat_NormalValueNat_SexID<>$s,'sex_mismatch',NULL),
|
||||
IF(nn.Nat_NormalValueNat_NormalValueTypeID IN(1,2) AND NOT $matchMinAge,'age_below_min',NULL),
|
||||
IF(nn.Nat_NormalValueNat_NormalValueTypeID IN(1,2) AND NOT $matchMaxAge,'age_above_max',NULL)
|
||||
) AS FailReason
|
||||
FROM nat_normalvalue nn
|
||||
LEFT JOIN nat_methode nm ON nm.Nat_MethodeID = nn.Nat_NormalValueNat_MethodeID
|
||||
WHERE nn.Nat_NormalValueNat_TestID = $natTestID
|
||||
AND nn.Nat_NormalValueIsActive = 'Y'
|
||||
AND nn.Nat_NormalValueIsAbnormal = 'N'
|
||||
ORDER BY
|
||||
CASE WHEN $m>0 AND nn.Nat_NormalValueNat_MethodeID=$m THEN 0 ELSE 1 END,
|
||||
nn.Nat_NormalValueNat_MethodeID,
|
||||
nn.Nat_NormalValueNat_NormalValueTypeID,
|
||||
nn.Nat_NormalValueID";
|
||||
|
||||
$qry = $this->db->query($sql);
|
||||
return $qry ? $qry->result_array() : [];
|
||||
}
|
||||
|
||||
private function _chk($name, $ok, $value, $note)
|
||||
{
|
||||
return [
|
||||
'check_name' => $name,
|
||||
'check_status' => $ok ? 'OK' : 'MISSING',
|
||||
'check_value' => $value,
|
||||
'check_note' => $note,
|
||||
];
|
||||
}
|
||||
|
||||
private function _query_one($sql)
|
||||
{
|
||||
$qry = $this->db->query($sql);
|
||||
if (!$qry) return 0;
|
||||
$row = $qry->row_array();
|
||||
return intval($row['Nat_NormalValueID'] ?? 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user