441 lines
18 KiB
PHP
441 lines
18 KiB
PHP
<?php
|
|
defined("BASEPATH") or exit("No direct script access allowed");
|
|
class Promise
|
|
{
|
|
|
|
function __construct()
|
|
{
|
|
$CI = &get_instance();
|
|
$this->db_smartone = $CI->load->database("default", true);
|
|
}
|
|
|
|
function get_schedule_results_grouped($test_ids, $x_datetime, $branch_id, $order_id = null)
|
|
{
|
|
// Validasi input
|
|
if (empty($test_ids) || empty($x_datetime) || empty($branch_id)) {
|
|
return array("status" => "ERR", "message" => "Parameter tidak lengkap", "data" => array());
|
|
}
|
|
|
|
// Konversi test_ids ke array integer
|
|
if (is_array($test_ids)) {
|
|
$test_ids_array = array_map('intval', $test_ids);
|
|
} else {
|
|
$test_ids_array = array_filter(array_map('intval', array_map('trim', explode(",", $test_ids))));
|
|
}
|
|
|
|
if (empty($test_ids_array)) {
|
|
return array("status" => "ERR", "message" => "Test IDs tidak valid", "data" => array());
|
|
}
|
|
|
|
$branch_id_escaped = intval($branch_id);
|
|
$test_ids_in = implode(",", $test_ids_array);
|
|
|
|
// Pre-calculate untuk optimasi
|
|
$x_datetime_ts = strtotime($x_datetime);
|
|
$time_str = date('H:i', $x_datetime_ts);
|
|
$date_str = date('Y-m-d', $x_datetime_ts);
|
|
$day_of_week = date('w', $x_datetime_ts); // 0=Sunday, 6=Saturday
|
|
$mysql_day_of_week = ($day_of_week == 0) ? 1 : $day_of_week + 1;
|
|
|
|
// ============================================
|
|
// STEP 1: Ambil data test (query sederhana)
|
|
// ============================================
|
|
$sql = "SELECT
|
|
T_TestID,
|
|
T_TestName,
|
|
T_TestSasCode,
|
|
T_TestParentT_TestID,
|
|
T_TestNat_TestID,
|
|
T_TestIsResult
|
|
FROM t_test
|
|
WHERE T_TestID IN ({$test_ids_in})
|
|
AND T_TestIsActive = 'Y'";
|
|
|
|
$query = $this->db_smartone->query($sql);
|
|
if (!$query) {
|
|
return array("status" => "ERR", "message" => "Gagal ambil data test", "data" => array());
|
|
}
|
|
|
|
$tests = $query->result_array();
|
|
$test_list = array();
|
|
$parent_test_ids = array();
|
|
$sas_codes = array();
|
|
|
|
// Proses test: pisahkan yang result dan yang parent
|
|
foreach ($tests as $test) {
|
|
if ($test['T_TestIsResult'] == 'Y') {
|
|
$test_list[$test['T_TestID']] = $test;
|
|
} else {
|
|
$parent_test_ids[] = $test['T_TestID'];
|
|
$sas_codes[] = $this->db_smartone->escape($test['T_TestSasCode']);
|
|
}
|
|
}
|
|
|
|
// Ambil child test dari parent (jika ada)
|
|
if (!empty($sas_codes)) {
|
|
$sql_parts = array();
|
|
foreach ($sas_codes as $sas_code) {
|
|
$sql_parts[] = "T_TestSasCode LIKE CONCAT({$sas_code}, '%')";
|
|
}
|
|
$sql = "SELECT
|
|
T_TestID,
|
|
T_TestName,
|
|
T_TestSasCode,
|
|
T_TestParentT_TestID,
|
|
T_TestNat_TestID,
|
|
T_TestIsResult
|
|
FROM t_test
|
|
WHERE (" . implode(" OR ", $sql_parts) . ")
|
|
AND T_TestIsActive = 'Y'
|
|
AND T_TestIsResult = 'Y'";
|
|
|
|
$query = $this->db_smartone->query($sql);
|
|
if ($query) {
|
|
$child_tests = $query->result_array();
|
|
foreach ($child_tests as $child) {
|
|
$test_list[$child['T_TestID']] = $child;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (empty($test_list)) {
|
|
return array("status" => "OK", "message" => "No test found", "data" => array());
|
|
}
|
|
|
|
// ============================================
|
|
// STEP 1.5: Ambil T_OrderDetailID jika order_id diberikan (setelah child test ditambahkan)
|
|
// ============================================
|
|
$order_detail_map = array(); // [test_id => order_detail_id]
|
|
if (!empty($order_id)) {
|
|
$order_id_escaped = intval($order_id);
|
|
// Ambil semua test_ids dari test_list (termasuk child yang baru ditambahkan)
|
|
$all_test_ids = array_keys($test_list);
|
|
$all_test_ids_in = implode(",", array_map('intval', $all_test_ids));
|
|
|
|
$sql = "SELECT
|
|
T_OrderDetailID,
|
|
T_OrderDetailT_TestID AS T_TestID
|
|
FROM t_orderdetail
|
|
WHERE T_OrderDetailT_OrderHeaderID = {$order_id_escaped}
|
|
AND T_OrderDetailT_TestID IN ({$all_test_ids_in})
|
|
AND T_OrderDetailIsActive = 'Y'";
|
|
|
|
$query = $this->db_smartone->query($sql);
|
|
if ($query) {
|
|
$order_details = $query->result_array();
|
|
foreach ($order_details as $od) {
|
|
$order_detail_map[$od['T_TestID']] = $od['T_OrderDetailID'];
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// STEP 2: Ambil schedule untuk semua test (query sederhana)
|
|
// ============================================
|
|
$nat_test_ids = array_unique(array_column($test_list, 'T_TestNat_TestID'));
|
|
$nat_test_ids_in = implode(",", array_map('intval', $nat_test_ids));
|
|
|
|
$sql = "SELECT
|
|
s.M_ScheduleID,
|
|
s.M_ScheduleFlagAtTime,
|
|
s.M_ScheduleAtTime,
|
|
s.M_ScheduleMinute,
|
|
s.M_ScheduleMonth,
|
|
s.M_ScheduleWeek,
|
|
s.M_ScheduleDay,
|
|
s.M_ScheduleHour,
|
|
s.M_ScheduleStartHourMinute,
|
|
s.M_ScheduleEndHourMinute,
|
|
sgt.M_ScheduleGroupTestNat_TestID AS Nat_TestID
|
|
FROM m_schedule s
|
|
INNER JOIN m_schedulegroup sg ON s.M_ScheduleM_ScheduleGroupID = sg.M_ScheduleGroupID
|
|
INNER JOIN m_schedulegrouptest sgt ON sg.M_ScheduleGroupID = sgt.M_ScheduleGroupTestM_ScheduleGroupID
|
|
WHERE s.M_ScheduleIsActive = 'Y'
|
|
AND sg.M_ScheduleGroupIsActive = 'Y'
|
|
AND sgt.M_ScheduleGroupTestIsActive = 'Y'
|
|
AND sg.M_ScheduleGroupM_BranchID = {$branch_id_escaped}
|
|
AND s.M_ScheduleDayOfWeek = {$mysql_day_of_week}
|
|
AND sgt.M_ScheduleGroupTestNat_TestID IN ({$nat_test_ids_in})
|
|
AND '{$time_str}' >= s.M_ScheduleStartHourMinute
|
|
AND '{$time_str}' <= s.M_ScheduleEndHourMinute";
|
|
|
|
$query = $this->db_smartone->query($sql);
|
|
if (!$query) {
|
|
return array("status" => "ERR", "message" => "Gagal ambil schedule", "data" => array());
|
|
}
|
|
|
|
$schedules = $query->result_array();
|
|
|
|
//$this->order_debug('get_schedule_results_grouped/get_schedule', $this->db_smartone->last_query(), $schedules, "Ambil schedule untuk semua test");
|
|
|
|
// ============================================
|
|
// STEP 3: Proses di PHP - hitung janji hasil untuk setiap test
|
|
// ============================================
|
|
$test_schedules = array(); // [test_id => [schedule1, schedule2, ...]]
|
|
|
|
foreach ($test_list as $test_id => $test) {
|
|
$test_schedules[$test_id] = array();
|
|
|
|
// Cari schedule untuk test ini
|
|
foreach ($schedules as $schedule) {
|
|
if ($schedule['Nat_TestID'] == $test['T_TestNat_TestID']) {
|
|
// Hitung janji hasil
|
|
if ($schedule['M_ScheduleFlagAtTime'] == 'Y') {
|
|
$janji_hasil = $date_str . ' ' . $schedule['M_ScheduleAtTime'] . ':00';
|
|
} else {
|
|
$janji_hasil_ts = $this->calculate_janji_hasil_ts($x_datetime_ts, $schedule);
|
|
$janji_hasil = date('Y-m-d H:i:s', $janji_hasil_ts);
|
|
|
|
$data_debug = array(
|
|
'test_id' => $test_id,
|
|
'test_name' => $test['T_TestName'],
|
|
'test_nat_test_id' => $test['T_TestNat_TestID'],
|
|
'schedule_id' => $schedule['M_ScheduleID'],
|
|
'schedule_flag_at_time' => $schedule['M_ScheduleFlagAtTime'],
|
|
'schedule_at_time' => $schedule['M_ScheduleAtTime'],
|
|
'schedule_month' => $schedule['M_ScheduleMonth'],
|
|
'schedule_week' => $schedule['M_ScheduleWeek'],
|
|
'schedule_day' => $schedule['M_ScheduleDay'],
|
|
'schedule_hour' => $schedule['M_ScheduleHour'],
|
|
'schedule_minute' => $schedule['M_ScheduleMinute'],
|
|
'schedule_start_hour_minute' => $schedule['M_ScheduleStartHourMinute'],
|
|
'schedule_end_hour_minute' => $schedule['M_ScheduleEndHourMinute']
|
|
);
|
|
//$this->order_debug('get_schedule_results_grouped/loop_schedule', '', $data_debug, "check schedule for test_id: $test_id");
|
|
}
|
|
|
|
// Convert day, hour, minute to total minutes
|
|
$tat_menit = ($schedule['M_ScheduleDay'] * 24 * 60) + ($schedule['M_ScheduleHour'] * 60) + $schedule['M_ScheduleMinute'];
|
|
|
|
$test_schedules[$test_id][] = array(
|
|
'ScheduleID' => $schedule['M_ScheduleID'],
|
|
'JanjiHasil' => $janji_hasil,
|
|
'JanjiHasil_TS' => strtotime($janji_hasil),
|
|
'M_ScheduleFlagAtTime' => $schedule['M_ScheduleFlagAtTime'],
|
|
'M_ScheduleAtTime' => $schedule['M_ScheduleAtTime'],
|
|
'TAT_Menit' => $tat_menit,
|
|
'M_ScheduleStartHourMinute' => $schedule['M_ScheduleStartHourMinute'],
|
|
'M_ScheduleEndHourMinute' => $schedule['M_ScheduleEndHourMinute']
|
|
);
|
|
}
|
|
}
|
|
|
|
// Jika tidak ada schedule langsung, cari dari parent atau sibling
|
|
if (empty($test_schedules[$test_id]) && !empty($test['T_TestParentT_TestID'])) {
|
|
$parent_id = $test['T_TestParentT_TestID'];
|
|
|
|
// Cari schedule dari parent
|
|
foreach ($schedules as $schedule) {
|
|
// Cek apakah ada test parent dengan nat_test_id yang sama
|
|
foreach ($tests as $parent_test) {
|
|
if ($parent_test['T_TestID'] == $parent_id &&
|
|
$parent_test['T_TestNat_TestID'] == $schedule['Nat_TestID']) {
|
|
// Hitung janji hasil
|
|
if ($schedule['M_ScheduleFlagAtTime'] == 'Y') {
|
|
$janji_hasil = $date_str . ' ' . $schedule['M_ScheduleAtTime'] . ':00';
|
|
} else {
|
|
$janji_hasil_ts = $this->calculate_janji_hasil_ts($x_datetime_ts, $schedule);
|
|
$janji_hasil = date('Y-m-d H:i:s', $janji_hasil_ts);
|
|
}
|
|
|
|
// Convert day, hour, minute to total minutes
|
|
$tat_menit = ($schedule['M_ScheduleDay'] * 24 * 60) + ($schedule['M_ScheduleHour'] * 60) + $schedule['M_ScheduleMinute'];
|
|
|
|
$test_schedules[$test_id][] = array(
|
|
'ScheduleID' => $schedule['M_ScheduleID'],
|
|
'JanjiHasil' => $janji_hasil,
|
|
'JanjiHasil_TS' => strtotime($janji_hasil),
|
|
'M_ScheduleFlagAtTime' => $schedule['M_ScheduleFlagAtTime'],
|
|
'M_ScheduleAtTime' => $schedule['M_ScheduleAtTime'],
|
|
'TAT_Menit' => $tat_menit,
|
|
'M_ScheduleStartHourMinute' => $schedule['M_ScheduleStartHourMinute'],
|
|
'M_ScheduleEndHourMinute' => $schedule['M_ScheduleEndHourMinute']
|
|
);
|
|
break 2; // Break dari kedua loop
|
|
}
|
|
}
|
|
}
|
|
|
|
// Jika masih tidak ada, cari dari sibling (test lain dengan parent yang sama)
|
|
if (empty($test_schedules[$test_id])) {
|
|
foreach ($test_list as $sibling_id => $sibling_test) {
|
|
if ($sibling_id != $test_id &&
|
|
$sibling_test['T_TestParentT_TestID'] == $parent_id) {
|
|
// Cari schedule sibling
|
|
foreach ($schedules as $schedule) {
|
|
if ($sibling_test['T_TestNat_TestID'] == $schedule['Nat_TestID']) {
|
|
if ($schedule['M_ScheduleFlagAtTime'] == 'Y') {
|
|
$janji_hasil = $date_str . ' ' . $schedule['M_ScheduleAtTime'] . ':00';
|
|
} else {
|
|
$janji_hasil_ts = $this->calculate_janji_hasil_ts($x_datetime_ts, $schedule);
|
|
$janji_hasil = date('Y-m-d H:i:s', $janji_hasil_ts);
|
|
}
|
|
|
|
// Convert day, hour, minute to total minutes
|
|
$tat_menit = ($schedule['M_ScheduleDay'] * 24 * 60) + ($schedule['M_ScheduleHour'] * 60) + $schedule['M_ScheduleMinute'];
|
|
|
|
$test_schedules[$test_id][] = array(
|
|
'ScheduleID' => $schedule['M_ScheduleID'],
|
|
'JanjiHasil' => $janji_hasil,
|
|
'JanjiHasil_TS' => strtotime($janji_hasil),
|
|
'M_ScheduleFlagAtTime' => $schedule['M_ScheduleFlagAtTime'],
|
|
'M_ScheduleAtTime' => $schedule['M_ScheduleAtTime'],
|
|
'TAT_Menit' => $tat_menit,
|
|
'M_ScheduleStartHourMinute' => $schedule['M_ScheduleStartHourMinute'],
|
|
'M_ScheduleEndHourMinute' => $schedule['M_ScheduleEndHourMinute']
|
|
);
|
|
break 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Jika masih tidak ada, default +24 jam
|
|
if (empty($test_schedules[$test_id])) {
|
|
$janji_hasil_ts = $x_datetime_ts + (24 * 3600);
|
|
$test_schedules[$test_id][] = array(
|
|
'ScheduleID' => null,
|
|
'JanjiHasil' => date('Y-m-d H:i:s', $janji_hasil_ts),
|
|
'JanjiHasil_TS' => $janji_hasil_ts,
|
|
'M_ScheduleFlagAtTime' => null,
|
|
'M_ScheduleAtTime' => null,
|
|
'TAT_Menit' => null,
|
|
'M_ScheduleStartHourMinute' => null,
|
|
'M_ScheduleEndHourMinute' => null
|
|
);
|
|
}
|
|
} elseif (empty($test_schedules[$test_id])) {
|
|
// Default +24 jam jika tidak ada schedule
|
|
$janji_hasil_ts = $x_datetime_ts + (24 * 3600);
|
|
$test_schedules[$test_id][] = array(
|
|
'ScheduleID' => null,
|
|
'JanjiHasil' => date('Y-m-d H:i:s', $janji_hasil_ts),
|
|
'JanjiHasil_TS' => $janji_hasil_ts,
|
|
'M_ScheduleFlagAtTime' => null,
|
|
'M_ScheduleAtTime' => null,
|
|
'TAT_Menit' => null,
|
|
'M_ScheduleStartHourMinute' => null,
|
|
'M_ScheduleEndHourMinute' => null
|
|
);
|
|
}
|
|
|
|
// Ambil schedule dengan janji hasil terbesar (ranking di PHP)
|
|
usort($test_schedules[$test_id], function($a, $b) {
|
|
return $b['JanjiHasil_TS'] - $a['JanjiHasil_TS'];
|
|
});
|
|
}
|
|
|
|
// ============================================
|
|
// STEP 4: Grouping berdasarkan tanggal dan jam (di PHP)
|
|
// ============================================
|
|
$grouped = array(); // [group_key => [tests]]
|
|
|
|
foreach ($test_schedules as $test_id => $schedules) {
|
|
$best_schedule = $schedules[0]; // Sudah di-sort, ambil yang terbesar
|
|
$test = $test_list[$test_id];
|
|
|
|
// Group key: tanggal + jam (tanpa detik)
|
|
$janji_ts = $best_schedule['JanjiHasil_TS'];
|
|
$group_key = date('Y-m-d H:i', $janji_ts);
|
|
|
|
if (!isset($grouped[$group_key])) {
|
|
$grouped[$group_key] = array(
|
|
'JanjiHasil' => $best_schedule['JanjiHasil'],
|
|
'JanjiHasil_Tanggal' => date('Y-m-d', $janji_ts),
|
|
'JanjiHasil_Waktu' => date('H:i:s', $janji_ts),
|
|
'TestIDs' => array(),
|
|
'TestNames' => array(),
|
|
'OrderDetailIDs' => array(), // Tambahkan untuk optimasi insert
|
|
'ScheduleID' => $best_schedule['ScheduleID'],
|
|
'M_ScheduleFlagAtTime' => $best_schedule['M_ScheduleFlagAtTime'],
|
|
'M_ScheduleAtTime' => $best_schedule['M_ScheduleAtTime'],
|
|
'TAT_Menit' => $best_schedule['TAT_Menit'],
|
|
'M_ScheduleStartHourMinute' => $best_schedule['M_ScheduleStartHourMinute'],
|
|
'M_ScheduleEndHourMinute' => $best_schedule['M_ScheduleEndHourMinute']
|
|
);
|
|
}
|
|
|
|
$grouped[$group_key]['TestIDs'][] = $test_id;
|
|
$grouped[$group_key]['TestNames'][] = $test['T_TestName'];
|
|
|
|
// Tambahkan OrderDetailID jika ada
|
|
if (!empty($order_detail_map[$test_id])) {
|
|
$grouped[$group_key]['OrderDetailIDs'][] = $order_detail_map[$test_id];
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// STEP 5: Format hasil akhir
|
|
// ============================================
|
|
$results = array();
|
|
foreach ($grouped as $group) {
|
|
$results[] = array(
|
|
'JanjiHasil_Tanggal' => $group['JanjiHasil_Tanggal'],
|
|
'JanjiHasil_Waktu' => $group['JanjiHasil_Waktu'],
|
|
'JanjiHasil' => $group['JanjiHasil'],
|
|
'TestIDs' => implode(',', $group['TestIDs']),
|
|
'TestNames' => implode(', ', $group['TestNames']),
|
|
'OrderDetailIDs' => !empty($group['OrderDetailIDs']) ? implode(',', $group['OrderDetailIDs']) : null, // Tambahkan OrderDetailIDs
|
|
'ScheduleID' => $group['ScheduleID'],
|
|
'M_ScheduleFlagAtTime' => $group['M_ScheduleFlagAtTime'],
|
|
'M_ScheduleAtTime' => $group['M_ScheduleAtTime'],
|
|
'TAT_Menit' => $group['TAT_Menit'],
|
|
'M_ScheduleStartHourMinute' => $group['M_ScheduleStartHourMinute'],
|
|
'M_ScheduleEndHourMinute' => $group['M_ScheduleEndHourMinute']
|
|
);
|
|
}
|
|
|
|
// Sort by tanggal dan waktu
|
|
usort($results, function($a, $b) {
|
|
$ts_a = strtotime($a['JanjiHasil']);
|
|
$ts_b = strtotime($b['JanjiHasil']);
|
|
return $ts_a - $ts_b;
|
|
});
|
|
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* Helper function untuk menghitung janji_hasil_ts berdasarkan schedule
|
|
* Memperhitungkan M_ScheduleMonth, M_ScheduleWeek, M_ScheduleDay, M_ScheduleHour, dan M_ScheduleMinute
|
|
*
|
|
* @param int $base_ts - Base timestamp
|
|
* @param array $schedule - Array schedule data
|
|
* @return int - Timestamp hasil perhitungan
|
|
*/
|
|
private function calculate_janji_hasil_ts($base_ts, $schedule)
|
|
{
|
|
$dt = new DateTime();
|
|
$dt->setTimestamp($base_ts);
|
|
|
|
// Tambahkan M_ScheduleMonth (jika ada)
|
|
if (!empty($schedule['M_ScheduleMonth']) && $schedule['M_ScheduleMonth'] > 0) {
|
|
$dt->modify('+' . intval($schedule['M_ScheduleMonth']) . ' months');
|
|
}
|
|
|
|
// Tambahkan M_ScheduleWeek (jika ada)
|
|
if (!empty($schedule['M_ScheduleWeek']) && $schedule['M_ScheduleWeek'] > 0) {
|
|
$dt->modify('+' . intval($schedule['M_ScheduleWeek']) . ' weeks');
|
|
}
|
|
|
|
// Tambahkan M_ScheduleDay (jika ada)
|
|
if (!empty($schedule['M_ScheduleDay']) && $schedule['M_ScheduleDay'] > 0) {
|
|
$dt->modify('+' . intval($schedule['M_ScheduleDay']) . ' days');
|
|
}
|
|
|
|
// Tambahkan M_ScheduleHour (jika ada)
|
|
if (!empty($schedule['M_ScheduleHour']) && $schedule['M_ScheduleHour'] > 0) {
|
|
$dt->modify('+' . intval($schedule['M_ScheduleHour']) . ' hours');
|
|
}
|
|
|
|
// Tambahkan M_ScheduleMinute (jika ada)
|
|
if (!empty($schedule['M_ScheduleMinute']) && $schedule['M_ScheduleMinute'] > 0) {
|
|
$dt->modify('+' . intval($schedule['M_ScheduleMinute']) . ' minutes');
|
|
}
|
|
|
|
return $dt->getTimestamp();
|
|
}
|
|
|
|
}
|