db_onedev = $this->load->database("onedev", true); $this->db_smartone = $this->load->database("onedev", true); // Daftar domain yang diizinkan mengakses API $allowedOrigins = [ 'https://devone.aplikasi.web.id', 'https://westerindo.com' // Tambahkan domain lain yang diizinkan di sini ]; // Ambil Origin dari request $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : ''; // Handle preflight request khusus if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { // Cek apakah origin ada dalam daftar yang diizinkan if (in_array($origin, $allowedOrigins)) { // Izinkan origin spesifik header("Access-Control-Allow-Origin: $origin"); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); // Ambil header yang diminta dari request preflight if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) { header('Access-Control-Allow-Headers: ' . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']); } else { header('Access-Control-Allow-Headers: Content-Type, Authorization, authorization, Accept, X-Requested-With'); } header('Access-Control-Max-Age: 86400'); // Cache preflight selama 24 jam header('Content-Length: 0'); header('Content-Type: text/plain'); http_response_code(200); } else { // Origin tidak diizinkan - berikan respons 403 header('Content-Type: text/plain'); http_response_code(403); echo 'Origin not allowed'; } exit(0); // Penting untuk menghentikan eksekusi lebih lanjut } // Header untuk request normal (non-OPTIONS) if (in_array($origin, $allowedOrigins)) { header("Access-Control-Allow-Origin: $origin"); header('Access-Control-Allow-Methods: GET, POST'); header('Access-Control-Allow-Headers: Content-Type, Authorization, authorization, Accept'); } } function save() { try { // Pastikan hanya menerima request POST if ($_SERVER['REQUEST_METHOD'] !== 'POST') { $this->sendResponse(405, ['error' => 'Method Not Allowed', 'message' => 'Hanya metode POST yang diizinkan']); return; } // Validasi API key/token $apiKey = $this->getAuthorizationHeader(); if (!$this->validateApiKeyWithPermission($apiKey, 'order:save')) { $this->sendResponse(401, ['error' => 'Unauthorized', 'message' => 'API key tidak valid']); return; } // Ambil dan validasi parameter filtering (jika ada) $filters = []; $errors = []; $allowedFilters = ['trx_date', 'trx_time', 'branch_code_lab', 'diagnose', 'fo_note', 'patient', 'details', 'type_order']; // For JSON input $jsonInput = file_get_contents('php://input'); if (!empty($jsonInput)) { $postData = json_decode($jsonInput, true); // Use $postData instead of $_POST foreach ($allowedFilters as $filter) { if (isset($postData[$filter])) { // Sanitasi input $filters[$filter] = $this->sanitizeInput($postData[$filter]); } } } $type_order = isset($filters['type_order']) ? $filters['type_order'] : ''; if ($type_order == '') { $errors[] = 'Parameter type order tidak boleh kosong (WALK_IN atau HOME_SERVICE)'; } if ($type_order != 'WALK_IN' && $type_order != 'HOME_SERVICE') { $errors[] = 'Parameter type order tidak valid (WALK_IN atau HOME_SERVICE)'; } $trx_date = isset($filters['trx_date']) ? $filters['trx_date'] : ''; $trx_time = isset($filters['trx_time']) ? $filters['trx_time'] : ''; if ($this->validateDate($trx_date)) { $trx_date = date('Y-m-d', strtotime($trx_date)); } else { $errors[] = 'Parameter tanggal transaksi tidak valid (format: YYYY-MM-DD)'; } if ($this->validateTime($trx_time)) { $trx_time = date('H:i:s', strtotime($trx_time)); } else { $errors[] = 'Parameter waktu transaksi tidak valid (format: HH:MM:SS)'; } if ($type_order == 'HOME_SERVICE') { $check_valid_datetime = $this->validateDateTimeNextDay($trx_date, $trx_time); if ($check_valid_datetime['is_valid'] == "N") { $errors[] = $check_valid_datetime['message']; } } $trx_datetime = $trx_date . ' ' . $trx_time; $patient = isset($filters['patient']) ? $filters['patient'] : []; $details = isset($filters['details']) ? $filters['details'] : []; $diagnose = isset($filters['diagnose']) ? $filters['diagnose'] : ''; $fo_note = isset($filters['fo_note']) ? $filters['fo_note'] : ''; if ($trx_date == '') { $errors[] = 'Parameter tanggal transaksi tidak boleh kosong'; } if ($trx_time == '') { $errors[] = 'Parameter waktu transaksi tidak boleh kosong'; } if ($trx_time == '') { $errors[] = 'Parameter waktu transaksi tidak boleh kosong'; } if ($trx_datetime < date('Y-m-d H:i:s')) { $errors[] = 'Parameter waktu transaksi tidak boleh kurang dari waktu sekarang'; } $branch_code_lab = isset($filters['branch_code_lab']) ? $filters['branch_code_lab'] : ''; if ($branch_code_lab == '') { $errors[] = 'Parameter branch_code_lab tidak boleh kosong'; } // Cek patient kosong if (count($patient) == 0) { $errors[] = 'Parameter patient tidak boleh kosong'; } if (count($details) == 0) { $errors[] = 'Parameter details tidak boleh kosong'; } // Jika patient dan details kosong, langsung return error if (!empty($errors)) { $prm_log = ['CHECK_PARAM', 'order/save', json_encode($errors)]; $this->sendResponse(400, ['error' => 'Bad Request', 'message' => $errors]); return; } // Validasi data patient $patient_name = $patient['name'];/*PATIENT_NAME (Required)*/ $patient_nik = $patient['nik'];/*NIK (Required)*/ if (strlen($patient_nik) != 16) { $errors[] = 'Parameter patient : nik harus 16 digit'; } $patient_gender = $patient['gender'];/*MALE, FEMALE (Required)*/ $patient_birthdate = $patient['birthdate'];/*YYYY-MM-DD (Required)*/ $patient_phone = $patient['phone'];/*081234567890 (Required)*/ // Validasi phone $patient_phone = preg_replace('/[^0-9]/', '', $patient_phone); if (substr($patient_phone, 0, 2) === '62') { $patient_phone = '0' . substr($patient_phone, 2); } // Validasi email $patient_email = $patient['email'];/*email@example.com (Required)*/ if (!$this->validateEmail($patient_email)) { $errors[] = 'Parameter patient : email tidak valid'; } $patient_job = isset($patient['job']) ? $patient['job'] : '';/*JOB_NAME (Optional)*/ $patient_nip = isset($patient['nip']) ? $patient['nip'] : '';/*NIP (Optional)*/ $patient_departement = isset($patient['job_departement']) ? $patient['job_departement'] : '';/*JOB_DEPARTMENT (Optional)*/ $patient_division = isset($patient['job_division']) ? $patient['job_division'] : '';/*JOB_DIVISION (Optional)*/ $patient_position = isset($patient['job_position']) ? $patient['job_position'] : '';/*JOB_POSITION (Optional)*/ $patient_location = isset($patient['job_location']) ? $patient['job_location'] : '';/*JOB_LOCATION (Optional)*/ $patient_address = $patient['address'];/*ADDRESS (Required)*/ $patient_province = $patient['pro_cd'];/*PROVINCE_CODE (Required)*/ $patient_city = $patient['kab_cd'];/*CITY_CODE (Required)*/ $patient_district = $patient['kec_cd'];/*DISTRICT_CODE (Required)*/ $patient_village = $patient['kel_cd'];/*VILLAGE_CODE (Required)*/ $patient_rt = isset($patient['rt']) ? $patient['rt'] : '';/*RT (Optional)*/ $patient_rw = isset($patient['rw']) ? $patient['rw'] : '';/*RW (Optional)*/ // Validasi kode wilayah if (strlen($patient_province) != 2) { $errors[] = 'Parameter patient : province harus 2 digit, provinsi tidak boleh kosong'; } if (strlen($patient_city) != 2) { $errors[] = 'Parameter patient : city harus 2 digit, kota tidak boleh kosong'; } if (strlen($patient_district) != 3) { $errors[] = 'Parameter patient : district harus 3 digit, kecamatan tidak boleh kosong'; } if (strlen($patient_village) != 3) { $errors[] = 'Parameter patient : village harus 3 digit, kelurahan tidak boleh kosong'; } // Cek required fields if (empty($patient_name) || !isset($patient['name'])) { $errors[] = 'Parameter patient : name tidak boleh kosong'; } if (empty($patient_nik) || !isset($patient['nik'])) { $errors[] = 'Parameter patient : nik tidak boleh kosong'; } if (empty($patient_gender) || !in_array($patient_gender, ['MALE', 'FEMALE']) || !isset($patient['gender'])) { $errors[] = 'Parameter patient : gender harus MALE atau FEMALE'; } if (empty($patient_birthdate) || !isset($patient['birthdate'])) { $errors[] = 'Parameter patient : birthdate tidak boleh kosong'; } if (!$this->validateDate($patient_birthdate)) { $errors[] = 'Parameter patient : birthdate tidak valid (format: YYYY-MM-DD dan tahun tidak boleh lebih besar dari tahun sekarang)'; } if (empty($patient_phone) || !isset($patient['phone'])) { $errors[] = 'Parameter patient : phone tidak boleh kosong'; } if (empty($patient_address) || !isset($patient['address'])) { $errors[] = 'Parameter patient : address tidak boleh kosong'; } // Kirim semua error jika ada if (!empty($errors)) { $prm_log = ['CHECK_PARAM', 'order/save', json_encode($errors)]; $log_error = $this->insert_log_error($sql, $prm_log); $this->sendResponse(400, [ 'error' => 'Bad Request', 'message' => $errors ]); return; } $regional_cd = $patient_province . $patient_city . $patient_district . $patient_village; if ($patient_gender == 'MALE') { $gender_id = 1; } else { $gender_id = 3; } //$this->db_smartone->trans_begin(); $sql = "SELECT * FROM config_website WHERE configWebsiteIsActive = 'Y' ORDER BY configWebsiteID DESC LIMIT 1"; $query = $this->db_smartone->query($sql); if (!$query) { $prm_log = ['SELECT_MGM_MCUONLINE', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat mengambil data proyek, config belum diatur']); return; } $rows_mcuonline = $query->result_array(); $mgm_mcuID = $rows_mcuonline[0]['configWebsiteMgm_McuID']; if (count($rows_mcuonline) == 0) { $this->sendResponse(200, ['error' => 'No Data Found', 'message' => 'Tidak ada data proyek yang ditemukan, di config_website']); return; } $sql = "SELECT Mgm_McuNumber as project_code, CorporateID as corporate_id, CorporateCode as corporate_code, Mgm_McuLabel as project_name FROM mgm_mcu JOIN corporate ON Mgm_McuCorporateID = CorporateID WHERE Mgm_mcuID = ?"; $query = $this->db_smartone->query($sql, $mgm_mcuID); if (!$query) { $prm_log = ['SELECT_MGM_MCU', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat mengambil data corporate dan proyek']); return; } $rows_mcu = $query->result_array(); if (count($rows_mcu) == 0) { $this->sendResponse(200, ['error' => 'No Data Found', 'message' => 'Tidak ada data proyek dan corporate yang ditemukan']); return; } $patient_corporate_id = $rows_mcu[0]['corporate_id']; $patient_corporate_code = $rows_mcu[0]['corporate_code']; $sql = "SELECT * FROM m_patient WHERE M_PatientIdentifierValue = ? AND M_PatientIsActive = 'Y' ORDER BY M_PatientID DESC LIMIT 1"; $query = $this->db_smartone->query($sql, $patient_nik); if (!$query) { $prm_log = ['SELECT_M_PATIENT', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat mengambil data pasien']); return; } $rows_patient = $query->result_array(); $check_duplicate_nat_tests = $this->check_duplicate_nat_tests($details); if ($check_duplicate_nat_tests['is_duplicate']) { $this->db_smartone->trans_rollback(); $message = "Terdapat duplikasi parameter pada pemeriksaan berikut:\n"; foreach ($check_duplicate_nat_tests['duplicate_pairs'] as $pair) { $message .= "- Pemeriksaan \"" . $pair['test1'] . "\" dan \"" . $pair['test2'] . "\" memiliki parameter yang sama\n"; } $prm_log = ['CHECK_DUPLICATE_NAT_TESTS', 'order/save', $message]; $log_error = $this->insert_log_error($sql, $prm_log); $this->sendResponse(400, ['error' => 'Bad Request', 'message' => $message]); return; } $this->db_smartone->trans_begin(); $arr_patient = [ 'mgm_mcu_id' => $mgm_mcuID, 'registered_by_corporate_id' => $patient_corporate_id, 'corporate_code' => $patient_corporate_code, 'no_reg' => '', 'm_title_id' => $gender_id, 'name' => $patient_name, 'gender' => $patient_gender, 'birthdate' => $patient_birthdate, 'nik' => $patient_nik, 'nip' => $patient_nip, 'job' => $patient_job, 'posisi' => $patient_position, 'divisi' => $patient_division, 'location' => $patient_location, 'departement' => $patient_departement, 'hp' => $patient_phone, 'email' => $patient_email, 'address' => $patient_address, 'address_regional_cd' => $regional_cd, 'address_rt' => $patient_rt, 'address_rw' => $patient_rw, 'address_country' => 'ID' ]; if (count($rows_patient) == 0) { $dt_patient = $this->insert_patient($arr_patient); if (!$dt_patient) { $prm_log = ['INSERT_PATIENT', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat menyimpan data pasien']); return; } $patient_id = $dt_patient['patient_id']; $patient_no_reg = $dt_patient['no_reg']; } else { $patient_id = $rows_patient[0]['M_PatientID']; $patient_no_reg = $rows_patient[0]['M_PatientNoReg']; } $arr_patient['patient_id'] = $patient_id; $arr_patient['patient_no_reg'] = $patient_no_reg; $arr_tests = []; foreach ($details as $k => $detail) { $arr_tests[] = $detail['test_sas_code']; } $string_tests = implode(',', $arr_tests); $check_exist_order = $this->check_exist_order($patient_nik, $string_tests, $trx_datetime); if ($check_exist_order['is_valid'] == 'N' || $check_exist_order['count'] > 0) { if ($check_exist_order['is_valid'] == 'N') { $prm_log = ['CHECK_EXIST_ORDER', 'order/save', $check_exist_order['query']]; $log_error = $this->insert_log_error($sql, $prm_log); } $this->db_smartone->trans_rollback(); $this->sendResponse(400, ['error' => 'Bad Request', 'message' => $check_exist_order['message']]); return; } $preregister_id = $this->insert_preregister($arr_patient, $string_tests, $type_order); if (!$preregister_id) { $prm_log = ['INSERT_PREREGISTER', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat menyimpan data preregister']); return; } $preregister_online_id = $this->preregister_online($preregister_id, $branch_code_lab, $trx_datetime, $diagnose, $fo_note, $patient_id, $patient_corporate_id, $mgm_mcuID, $type_order, $details); if ($preregister_online_id['status'] == false) { $prm_log = ['INSERT_PREREGISTER_ONLINE', 'order/save', $preregister_online_id['query']]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat menyimpan data preregister online']); return; } $sql = "SELECT * FROM preregister_online WHERE PreregisterOnlineID = ? AND PreregisterOnlineIsActive = 'Y' LIMIT 1"; $query = $this->db_smartone->query($sql, $preregister_online_id['data']); if (!$query) { $prm_log = ['SELECT_PREREGISTER_ONLINE', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat mengambil data preregister online']); return; } $arr_preregister_online = $query->row_array(); $qrcode_booking = $arr_preregister_online['PreregisterOnlineQRCode']; $order_number = $arr_preregister_online['PreregisterOnlineOrderNumber']; $generate_img = $this->genbookingqrcode($qrcode_booking . '_' . $order_number); $dt_order = [ 'qrcode_booking' => $qrcode_booking, 'order_number' => $order_number, 'image_qrcode' => $generate_img ]; $this->db_smartone->trans_commit(); $response = [ 'status' => 'success', 'data' => $dt_order, 'meta' => [ 'message' => 'Data berhasil disimpan' ] ]; // --- 5. KIRIM RESPONSE --- $this->sendResponse(200, $response); } catch (PDOException $e) { // Log error tapi jangan tampilkan detail ke user error_log('Database error: ' . $e->getMessage()); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat mengambil data']); } catch (Exception $e) { error_log('API error: ' . $e->getMessage()); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan dalam pemrosesan']); } } function register() { $this->db_smartone->trans_begin(); $data = json_decode(file_get_contents("php://input"), true); $branch_code_lab = $data['branch_code_lab'] ?? ''; $trx_datetime = $data['trx_datetime'] ?? ''; $patient_birthdate = $data['patient_birthdate'] ?? ''; $preregister_id = $data['preregister_id'] ?? ''; $diagnose = $data['diagnose'] ?? ''; $fo_note = $data['fo_note'] ?? ''; $patient_id = $data['patient_id'] ?? ''; $patient_corporate_id = $data['patient_corporate_id'] ?? ''; $mgm_mcuID = $data['mgm_mcuID'] ?? ''; $details = $data['details'] ?? ''; // print_r($details); // exit; $sql = "SELECT M_BranchID as branch_id FROM m_branch WHERE M_BranchCodeLab = ?"; $query = $this->db_smartone->query($sql, $branch_code_lab); if (!$query) { $prm_log = ['SELECT_M_BRANCH', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat mengambil data branch']); return; } $rows_branch = $query->result_array(); if (count($rows_branch) == 0) { $prm_log = ['NOTFOUND_M_BRANCH', 'order/save', $branch_code_lab]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(400, ['error' => 'Bad Request', 'message' => 'Branch code lab tidak ditemukan']); return; } //get branch id $branch_id = $rows_branch[0]['branch_id']; //get doctor pj $sql = "SELECT M_DoctorPjM_DoctorID as doctorid FROM m_doctorpj WHERE M_DoctorPjIsActive = 'Y' AND M_DoctorPjIsPJ = 'Y'"; $query = $this->db_smartone->query($sql); if (!$query) { $prm_log = ['SELECT_M_DOCTOR_PJ', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat mengambil data doctor PJ']); return; } $rows_doctor_pj = $query->result_array(); if (count($rows_doctor_pj) == 0) { $prm_log = ['NOTFOUND_M_DOCTOR_PJ', 'order/save', $branch_code_lab]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(400, ['error' => 'Bad Request', 'message' => 'Tidak ada doctor PJ yang ditemukan']); return; } if (count($rows_doctor_pj) > 1) { $pj1 = $rows_doctor_pj[0]["doctorid"]; $pj2 = $rows_doctor_pj[1]["doctorid"]; } elseif (count($rows_doctor_pj) == 1) { $pj1 = $rows_doctor_pj[0]["doctorid"]; $pj2 = 0; } //count age $date = date("Y-m-d"); $patient_age = $this->count_age($patient_birthdate, $date); $sql = "SELECT fn_numbering_cpone_transaction('T',?) xnumber"; $query = $this->db_smartone->query($sql, $branch_id); if (!$query) { $prm_log = ['SELECT_FN_NUMBERING_CPONE_TRANSACTION', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat membuat nomor transaksi']); return; } $rows_no_trans = $query->result_array(); //get no trans $no_trans = $rows_no_trans[0]['xnumber']; //insert header $sql_header = "INSERT INTO t_orderheader (T_OrderHeaderM_StatusCode, T_OrderHeaderM_BranchID, T_OrderHeaderDate, T_OrderHeaderLabNumber, T_OrderHeaderM_PatientID, T_OrderHeaderCorporateID, T_OrderHeaderMgm_McuID, T_OrderHeaderM_PatientAge, T_OrderHeaderPjM_DoctorID, T_OrderHeaderPj2M_DoctorID, T_OrderHeaderDiagnose, T_OrderHeaderFoNote, T_OrderHeaderSamplingNote, T_OrderHeaderResultNote, T_OrderHeaderFoNoteM_UserID, T_OrderHeaderSamplingNoteM_UserID, T_OrderHeaderResultNoteM_UserID, T_OrderHeaderCreated, T_OrderHeaderLastUpdated, T_OrderHeaderCreatedUserID, T_OrderHeaderLastUpdatedUserID) VALUES(?,?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW(),?,?)"; $prm_header = [ 'RG', $branch_id, $no_trans, $patient_id, $patient_corporate_id, $mgm_mcuID, $patient_age, $pj1, $pj2, $diagnose, $fo_note, '', '', $fo_note != '' ? 565 : 0, 0, 0, 565, 565 ]; $query_header = $this->db_smartone->query($sql_header, $prm_header); if (!$query_header) { $prm_log = ['INSERT_T_ORDERHEADER', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat menyimpan data header']); return; } //get header id $header_id = $this->db_smartone->insert_id(); $sqlheaderlang = "INSERT INTO t_orderheaderlang (T_OrderHeaderLangT_OrderHeaderID, T_OrderHeaderLangM_LangID, T_OrderHeaderLangCreated, T_OrderHeaderLangCreatedUserID, T_OrderHeaderLangLastUpdated, T_OrderHeaderLangLastUpdatedUserID) VALUES(?,?,NOW(),?,NOW(),?)"; $prm_header_lang = [ $header_id, 1, 565, 565 ]; $query_header_lang = $this->db_smartone->query($sqlheaderlang, $prm_header_lang); if (!$query_header_lang) { $prm_log = ['INSERT_T_ORDERHEADER_LANG', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat menyimpan data header lang']); return; } //insert detail order foreach ($details as $k => $detail) { $sql_orderdetailorder = "INSERT INTO t_orderdetailorder( T_OrderDetailOrderT_OrderHeaderID, T_OrderDetailOrderT_TestID, T_OrderDetailOrderT_TestName, T_OrderDetailOrderIsPacket, T_OrderDetailOrderPacketType, T_OrderDetailOrderT_PacketID, T_OrderDetailOrderT_PacketName, T_OrderDetailOrderCreated, T_OrderDetailOrderCreatedUserID, T_OrderDetailOrderLastUpdated, T_OrderDetailOrderLastUpdatedUserID, T_OrderDetailOrderJsonChildren ) VALUES(?,?,?,?,?,?,?,NOW(),565,NOW(),565,'')"; $prm_detail_order = [ $header_id, $detail['px_type'] == 'PX' ? $detail['test_id'] : '', $detail['px_type'] == 'PX' ? $detail['test_name'] : '', $detail['px_type'] != 'PX' ? 'Y' : 'N', $detail['px_type'] != 'PX' ? $detail['px_type'] : '', $detail['px_type'] != 'PX' ? $detail['test_id'] : '', $detail['px_type'] != 'PX' ? $detail['test_name'] : '' ]; $query_detail_order = $this->db_smartone->query($sql_orderdetailorder, $prm_detail_order); if (!$query_detail_order) { $prm_log = ['INSERT_T_ORDERDETAILORDER', 'order/save', $this->db_smartone->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => 'Terjadi kesalahan saat menyimpan data detail order']); return; } $detail_order_id = $this->db_smartone->insert_id(); if ($detail['px_type'] != 'PX') { if (count($detail['child_test']) == 0) { $message = "Detail packet tidak boleh kosong"; $prm_log = ['INSERT_T_ORDERDETAILORDER', 'order/save', $message]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(400, ['error' => 'Bad Request', 'message' => $message]); return; } foreach ($detail['child_test'] as $k => $child_test_packet) { $child_test_packet['test_id'] = $child_test_packet['T_TestID']; $child_test_packet['test_name'] = $child_test_packet['T_TestName']; $detail_insert = $this->insert_order_detail($header_id, $detail_order_id, $child_test_packet); if ($detail_insert['status'] == false) { $message = "Terjadi kesalahan saat menyimpan data detail order " . $child_test_packet['test_name']; $prm_log = ['INS_T_ORDERDETAILPACKET', 'order/save', json_encode($detail_insert)]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => $message, 'data' => $detail_insert]); return; } } } else { $detail_insert = $this->insert_order_detail($header_id, $detail_order_id, $detail); if ($detail_insert['status'] == false) { $message = "Terjadi kesalahan saat menyimpan data detail order " . $detail['test_name']; $prm_log = ['INS_T_ORDERDETAILSINGLE', 'order/save', json_encode($detail_insert)]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => $message, 'data' => $detail_insert]); return; } } } $generate_sample_lab = $this->generate_sample_lab($header_id); if ($generate_sample_lab['status'] == false) { $message = $generate_sample_lab['message']; $prm_log = ['GENERATE_SAMPLE_LAB', 'order/save', json_encode($generate_sample_lab)]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => $message, 'data' => $detail_insert]); return; } $generate_location = $this->generate_location($header_id, $mgm_mcuID, $branch_id); if ($generate_location['status'] == false) { $message = $generate_location['message']; $prm_log = ['GENERATE_LOCATION', 'order/save', json_encode($generate_location)]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => $message, 'data' => $detail_insert]); return; } $generate_req = $this->generate_req($header_id, ['status' => 'Y', 'reqs' => '[]']); if ($generate_req['status'] == false) { $message = $generate_req['message']; $prm_log = ['GENERATE_REQ', 'order/save', json_encode($generate_req)]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => $message, 'data' => $detail_insert]); return; } $sql_preregister = "UPDATE mcu_preregister_patients SET Mcu_PreregisterPatientsIsRegistered = 'Y', Mcu_PreregisterPatientsT_OrderHeaderID = ? WHERE Mcu_PreregisterPatientsID = ?"; $prm_preregister = [ $header_id, $preregister_id ]; $query_preregister = $this->db_smartone->query($sql_preregister, $prm_preregister); if (!$query_preregister) { $message = 'Terjadi kesalahan saat menyimpan data preregister'; $prm_log = ['UPDATE_MCU_PREREGISTER_PATIENTS', 'order/save', json_encode($query_preregister)]; $log_error = $this->insert_log_error($sql, $prm_log); $this->db_smartone->trans_rollback(); $this->sendResponse(500, ['error' => 'Internal Server Error', 'message' => $message, 'data' => $detail_insert]); return; } $sql = "SELECT * FROM t_orderheader JOIN t_orderdetail ON T_OrderDetailT_OrderHeaderID = T_OrderHeaderID AND T_OrderDetailIsActive = 'Y' WHERE T_OrderHeaderID = ?"; $query_orderheader = $this->db_smartone->query($sql, [$header_id]); if (!$query_orderheader) { $prm_log = ['SELECT_T_ORDERHEADER', 'order/save', $this->db_smartone->last_query()]; $insert_log_error = $this->insert_log_error($sql, $prm_log); } //echo $this->db_smartone->last_query(); $x_data_array = $query_orderheader->result_array(); $lab_number = $x_data_array[0]['T_OrderHeaderLabNumber']; $x_data = json_encode($x_data_array); $sqllog = "INSERT INTO order_log( orderLogType, orderLogT_OrderHeaderID, orderLogJSONBefore, orderLogJSONAfter, orderLogCreated, orderLogUserID) VALUES ('REGISTER',?,'',?,now(),565)"; $querylog = $this->db_smartone->query($sqllog, [$header_id, $x_data]); if (!$querylog) { $prm_log = ['INSERT_ORDER_LOG', 'order/save', $this->db_smartone->last_query()]; $insert_log_error = $this->insert_log_error($sql, $prm_log); } $genqrcode = $this->genqrcode($lab_number, $header_id); $genpatientqrcode = $this->genpatientqrcode($lab_number); $dt_order = [ 'status' => 'OK', 'order_id' => $x_data_array[0]['T_OrderHeaderID'], 'order_date' => $x_data_array[0]['T_OrderHeaderDate'], 'lab_number' => $lab_number, 'qrcode' => $genqrcode, 'patient_qrcode' => $genpatientqrcode ]; $this->db_smartone->trans_commit(); echo json_encode($dt_order); } function genqrcode($nomorlab, $id) { $this->load->library('ciqrcode'); //pemanggilan library QR CODE $home_dir = "/home/one/project/one/"; $target_dir = $home_dir . "one-media/one-qrcontrolcard/"; $config['cacheable'] = false; //boolean, the default is true //$config['cachedir'] = './assets/'; //string, the default is application/cache/ //$config['errorlog'] = './assets/'; //string, the default is application/logs/ $config['imagedir'] = $target_dir; //direktori penyimpanan qr code $config['quality'] = true; //boolean, the default is true $config['size'] = '1024'; //interger, the default is 1024 $config['black'] = array(224, 255, 255); // array, default is array(255,255,255) $config['white'] = array(70, 130, 180); // array, default is array(0,0,0) $this->ciqrcode->initialize($config); $image_name = "qrcode_" . $nomorlab . ".png"; //buat name dari qr code sesuai dengan nim $params['data'] = "https://cpone.aplikasi.web.id/one-ui/test/vuex/cpone-control-card/?noreg=" . $nomorlab . "&id=" . $id; //data yang akan di jadikan QR CODE $params['level'] = 'H'; //H=High $params['size'] = 10; $params['savename'] = $config['imagedir'] . $image_name; //simpan image QR CODE ke folder assets/images/ $this->ciqrcode->generate($params); // fungsi untuk generate QR CODE return "https://devcpone.aplikasi.web.id/one-media/one-qrcontrolcard/" . $image_name; } function genpatientqrcode($nomorlab) { $this->load->library('ciqrcode'); //pemanggilan library QR CODE $home_dir = "/home/one/project/one/"; $target_dir = $home_dir . "one-media/one-qrpatient/"; $config['cacheable'] = false; //boolean, the default is true //$config['cachedir'] = './assets/'; //string, the default is application/cache/ //$config['errorlog'] = './assets/'; //string, the default is application/logs/ $config['imagedir'] = $target_dir; //direktori penyimpanan qr code $config['quality'] = true; //boolean, the default is true $config['size'] = '1024'; //interger, the default is 1024 $config['black'] = array(224, 255, 255); // array, default is array(255,255,255) $config['white'] = array(70, 130, 180); // array, default is array(0,0,0) $this->ciqrcode->initialize($config); $image_name = "patient_qr_" . $nomorlab . ".png"; //buat name dari qr code sesuai dengan nim $params['data'] = $nomorlab; //data yang akan di jadikan QR CODE $params['level'] = 'H'; //H=High $params['size'] = 10; $params['savename'] = $config['imagedir'] . $image_name; //simpan image QR CODE ke folder assets/images/ $this->ciqrcode->generate($params); // fungsi untuk generate QR CODE return "https://devcpone.aplikasi.web.id/one-media/one-qrpatient/" . $image_name; //echo "selesai"; } function genbookingqrcode($nomorbooking) { $this->load->library('ciqrcode'); //pemanggilan library QR CODE $home_dir = "/home/one/project/one/"; $target_dir = $home_dir . "one-media/one-qrpatient/"; $config['cacheable'] = false; //boolean, the default is true //$config['cachedir'] = './assets/'; //string, the default is application/cache/ //$config['errorlog'] = './assets/'; //string, the default is application/logs/ $config['imagedir'] = $target_dir; //direktori penyimpanan qr code $config['quality'] = true; //boolean, the default is true $config['size'] = '1024'; //interger, the default is 1024 $config['black'] = array(224, 255, 255); // array, default is array(255,255,255) $config['white'] = array(70, 130, 180); // array, default is array(0,0,0) $this->ciqrcode->initialize($config); $image_name = "booking_qr_" . $nomorbooking . ".png"; //buat name dari qr code sesuai dengan nim $params['data'] = $nomorbooking; //data yang akan di jadikan QR CODE $params['level'] = 'H'; //H=High $params['size'] = 10; $params['savename'] = $config['imagedir'] . $image_name; //simpan image QR CODE ke folder assets/images/ $this->ciqrcode->generate($params); // fungsi untuk generate QR CODE return "https://" . $_SERVER['HTTP_HOST'] . "/one-media/one-qrpatient/" . $image_name; //echo "selesai"; } function insert_order_detail($header_id, $detail_order_id, $detail) { // Buat array untuk informasi error/success $result = [ 'status' => true, 'message' => 'Success', 'test_name' => isset($detail['test_name']) ? $detail['test_name'] : '', 'test_id' => isset($detail['test_id']) ? $detail['test_id'] : '', 'test_code' => '', 'error_type' => '', 'error_detail' => [] ]; // Cek data test $sql = "SELECT * FROM t_test WHERE T_TestID = ?"; $query = $this->db_smartone->query($sql, $detail['test_id']); if (!$query) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat mengambil data test'; $result['error_type'] = 'DB_QUERY_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query() ]; return $result; } $rows_test = $query->result_array(); if (count($rows_test) == 0) { $result['status'] = false; $result['message'] = 'Test tidak ditemukan'; $result['error_type'] = 'TEST_NOT_FOUND'; return $result; } $dt_test = $rows_test[0]; //print_r($dt_test); //return false; // Update dengan data test yang benar dari database $result['test_name'] = $dt_test['T_TestName']; $result['test_code'] = $dt_test['T_TestCode']; $result['test_sas_code'] = $dt_test['T_TestSasCode']; $price = isset($detail['T_PriceAmount']) ? $detail['T_PriceAmount'] : $detail['price']; $disc = isset($detail['T_PriceDisc']) ? $detail['T_PriceDisc'] : $detail['disc']; $disc_rp = isset($detail['T_PriceDiscRp']) ? $detail['T_PriceDiscRp'] : $detail['disc_rp']; $subtotal = isset($detail['T_PriceSubTotal']) ? $detail['T_PriceSubTotal'] : $detail['subtotal']; $total = isset($detail['T_PriceTotal']) ? $detail['T_PriceTotal'] : $detail['total']; // Query insert order detail $sql_orderdetail = "INSERT INTO t_orderdetail( T_OrderDetailT_OrderHeaderID, T_OrderDetailT_OrderDetailOrderID, T_OrderDetailT_TestID, T_OrderDetailT_TestCode, T_OrderDetailT_TestSasCode, T_OrderDetailT_TestName, T_OrderDetailT_TestIsResult, T_OrderDetailT_TestIsPanel, T_OrderDetailT_TestIsPanelChildren, T_OrderDetailT_TestIsPanelChildrenPrintNota, T_OrderDetailT_TestIsPrice, T_OrderDetailIsCito, T_OrderDetailPrice, T_OrderDetailPriceForDisc, T_OrderDetailDisc, T_OrderDetailDiscAmount, T_OrderDetailDiscTotal, T_OrderDetailTotal, T_OrderDetailReq, T_OrderDetailReqNote, T_OrderDetailUserID, T_OrderDetailCreated, T_OrderDetailLastUpdated ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,'N','',565,NOW(),NOW())"; $prm_orderdetail = [ $header_id, $detail_order_id, $dt_test['T_TestID'], $dt_test['T_TestCode'], $dt_test['T_TestSasCode'], $dt_test['T_TestName'], $dt_test['T_TestIsResult'], 'N', 'N', 'N', $dt_test['T_TestIsPrice'], 'N', $dt_test['T_TestIsPrice'] == 'N' ? 0 : $price, $dt_test['T_TestIsPrice'] == 'N' ? 0 : $price, $dt_test['T_TestIsPrice'] == 'N' ? 0 : $disc, $dt_test['T_TestIsPrice'] == 'N' ? 0 : $disc_rp, $dt_test['T_TestIsPrice'] == 'N' ? 0 : $subtotal, $dt_test['T_TestIsPrice'] == 'N' ? 0 : $total ]; $query_orderdetail = $this->db_smartone->query($sql_orderdetail, $prm_orderdetail); if (!$query_orderdetail) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat menyimpan data detail order'; $result['error_type'] = 'INSERT_DETAIL_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query() ]; return $result; } // Ambil child test $sql = "SELECT * FROM t_test WHERE T_TestSasCode LIKE ? AND T_TestIsActive = 'Y' AND T_TestSasCode != ?"; $query = $this->db_smartone->query($sql, [$dt_test['T_TestSasCode'] . '%', $dt_test['T_TestSasCode']]); if (!$query) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat mengambil data child test'; $result['error_type'] = 'CHILD_TEST_QUERY_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query(), 'parent_test' => [ 'id' => $dt_test['T_TestID'], 'name' => $dt_test['T_TestName'], 'code' => $dt_test['T_TestCode'], 'sas_code' => $dt_test['T_TestSasCode'] ] ]; return $result; } $rows_test_child = $query->result_array(); if (count($rows_test_child) > 0) { // Tambahkan informasi jumlah child test yang ditemukan $result['child_tests_count'] = count($rows_test_child); foreach ($rows_test_child as $k_child => $test_child) { $sql_orderdetail = "INSERT INTO t_orderdetail( T_OrderDetailT_OrderHeaderID, T_OrderDetailT_OrderDetailOrderID, T_OrderDetailT_TestID, T_OrderDetailT_TestCode, T_OrderDetailT_TestSasCode, T_OrderDetailT_TestName, T_OrderDetailT_TestIsResult, T_OrderDetailT_TestIsPanel, T_OrderDetailT_TestIsPanelChildren, T_OrderDetailT_TestIsPanelChildrenPrintNota, T_OrderDetailT_TestIsPrice, T_OrderDetailIsCito, T_OrderDetailPrice, T_OrderDetailPriceForDisc, T_OrderDetailDisc, T_OrderDetailDiscAmount, T_OrderDetailDiscTotal, T_OrderDetailTotal, T_OrderDetailReq, T_OrderDetailReqNote, T_OrderDetailUserID, T_OrderDetailCreated, T_OrderDetailLastUpdated ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,'N','',565,NOW(),NOW())"; $prm_orderdetail = [ $header_id, $detail_order_id, $test_child['T_TestID'], $test_child['T_TestCode'], $test_child['T_TestSasCode'], $test_child['T_TestName'], $test_child['T_TestIsResult'], 'N', 'N', 'N', $test_child['T_TestIsPrice'], 'N', 0, 0, 0, 0, 0, 0 ]; $query_child = $this->db_smartone->query($sql_orderdetail, $prm_orderdetail); if (!$query_child) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat menyimpan data child test'; $result['error_type'] = 'INSERT_CHILD_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query(), 'child_index' => $k_child + 1, 'total_children' => count($rows_test_child), 'child_test' => [ 'id' => $test_child['T_TestID'], 'name' => $test_child['T_TestName'], 'code' => $test_child['T_TestCode'], 'sas_code' => $test_child['T_TestSasCode'] ], 'parent_test' => [ 'id' => $dt_test['T_TestID'], 'name' => $dt_test['T_TestName'], 'code' => $dt_test['T_TestCode'], 'sas_code' => $dt_test['T_TestSasCode'] ] ]; return $result; } } } // Jika semua proses berhasil if (count($rows_test_child) > 0) { $result['message'] = 'Berhasil menyimpan data test utama dan ' . count($rows_test_child) . ' child test'; } else { $result['message'] = 'Berhasil menyimpan data test'; } return $result; } function generate_sample_lab($header_id) { $result = [ 'status' => true, 'message' => 'Success', 'error_type' => '', 'error_detail' => [] ]; $userid = 565; $counter_barcode = 1; $sql = "SELECT T_OrderHeaderLabNumber, T_TestID, T_SampleTypeID , T_SampleTypeSuffix, T_SampleStationIsNonLab, T_SampleStationID FROM t_orderheader JOIN t_orderdetail ON t_orderheaderid = t_orderdetailt_orderheaderid AND t_orderdetailIsActive = 'Y' JOIN t_test ON t_orderdetailt_testid = t_testid AND T_TestIsResult = 'Y' JOIN t_sampletype ON T_TestT_SampleTypeID = T_SampleTypeID JOIN t_bahan ON T_SampleTypeT_BahanID = T_BahanID JOIN t_samplestation ON T_BahanT_SampleStationID = T_SampleStationID WHERE T_OrderHeaderID = ? GROUP BY T_SampleTypeID"; $qry = $this->db_smartone->query($sql, $header_id); if (!$qry) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat mengambil data sample'; $result['error_type'] = 'SAMPLE_QUERY_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query() ]; } $data_samples = $qry->result_array(); if (count($data_samples) > 0) { foreach ($data_samples as $k => $v) { $lab_no = $v['T_OrderHeaderLabNumber']; $test_id = $v['T_TestID']; $sample_id = $v['T_SampleTypeID']; $sample_code = $v['T_SampleTypeSuffix']; $barcode = $lab_no . $sample_code; $isnonlab = $v['T_SampleStationIsNonLab']; $samplestation_id = $v['T_SampleStationID']; if ($counter_barcode == 1) { $barcode = $barcode . $counter_barcode; $sql = "INSERT INTO t_barcodelab( T_BarcodeLabT_OrderHeaderID, T_BarcodeLabBarcode, T_BarcodeLabT_SampleTypeID, T_BarcodeLabCounter) VALUES (?,?,?,?)"; $prm_barcode = [ $header_id, $barcode, $sample_id, $counter_barcode ]; $qry = $this->db_smartone->query($sql, $prm_barcode); //echo $this->db_smartone->last_query(); if (!$qry) { $this->db_smartone->trans_rollback(); $this->sys_error_db(["status" => "ERR", "message" => "insert t_barcodelab | " . $this->db_smartone->error()["message"], "debug" => $this->db_smartone->last_query()]); exit; } $last_id_barcode = $this->db_smartone->insert_id(); if ($isnonlab == "") { $sql = "INSERT INTO t_ordersample( T_OrderSampleT_OrderHeaderID, T_OrderSampleT_SampleTypeID, T_OrderSampleT_BarcodeLabID, T_OrderSampleBarcode, T_OrderSampleT_SampleStationID, T_OrderSampleCreated) VALUES (?,?,?,?,?,NOW())"; $prm_ordersample = [ $header_id, $sample_id, $last_id_barcode, $barcode, $samplestation_id ]; $qry = $this->db_smartone->query($sql, $prm_ordersample); if (!$qry) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat menyimpan data sample ' . $sample_code; $result['error_type'] = 'SAMPLE_INSERT_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query() ]; } } } $sql = "SELECT MAX(T_BarcodeLabCounter) as ctr FROM t_barcodelab WHERE T_BarcodeLabT_OrderHeaderID = ? AND T_BarcodeLabBarcode LIKE CONCAT(?, '%') AND T_BarcodeLabIsActive = 'Y'"; $qry = $this->db_smartone->query($sql, [$header_id, $barcode]); if ($qry) { $ctr = $qry->row()->ctr; $counter_barcode = $ctr + 1; } else { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat mengambil data counter barcode'; $result['error_type'] = 'COUNTER_BARCODE_QUERY_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query() ]; } } } return $result; } function generate_location($header_id, $mcuid, $branch_id) { $result = [ 'status' => true, 'message' => 'Success', 'error_type' => '', 'error_detail' => [] ]; $userid = 565; $sql = "SELECT T_SampleStationID,T_SampleStationName FROM t_orderdetail JOIN t_test ON T_OrderDetailT_TestID = T_TestID AND T_TestIsActive = 'Y' JOIN t_sampletype ON T_TestT_SampleTypeID = T_SampleTypeID JOIN t_bahan ON T_SampleTypeT_BahanID = T_BahanID JOIN t_samplestation ON T_BahanT_SampleStationID = T_SampleStationID WHERE T_OrderDetailT_OrderHeaderID = ? GROUP BY T_SampleStationID "; $qry = $this->db_smartone->query($sql, $header_id); $data_samples = $qry->result_array(); foreach ($data_samples as $k => $v) { $sample_id = $v['T_SampleStationID']; $sql = "SELECT M_LocationID as loc_id FROM m_location WHERE M_LocationT_SampleStationID = ? ORDER BY M_LocationPriority DESC, M_LocationID ASC LIMIT 1"; $qry = $this->db_smartone->query($sql, $sample_id); if (!$qry) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat mengambil data lokasi ' . $v['T_SampleStationName']; $result['error_type'] = 'LOCATION_QUERY_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query() ]; } $loc_id = $qry->row()->loc_id; $sql = "INSERT INTO t_order_location( T_OrderLocationT_OrderHeaderID, T_OrderLocationM_LocationID, T_OrderLocationT_SampleStationID, T_OrderLocationCreated, T_OrderLocationLastUpdated, T_OrderLocationUserID) VALUES (?,?,?,NOW(),NOW(),?)"; $prm_orderlocation = [ $header_id, $loc_id, $sample_id, $userid ]; $qry = $this->db_smartone->query($sql, $prm_orderlocation); if (!$qry) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat menyimpan data lokasi'; $result['error_type'] = 'ORDER_LOCATION_INSERT_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query() ]; } } return $result; } function generate_req($header_id, $req) { $userid = 565; $result = [ 'status' => true, 'message' => 'Success', 'error_type' => '', 'error_detail' => [] ]; $sql = $this->db_smartone->query("SELECT Nat_PositionID as req_id FROM nat_position WHERE Nat_PositionCode = 'FO'")->row(); $req_id = $sql->req_id; $req_status = $req['status']; $req_tmp = "0"; $req['reqs'] = json_decode($req['reqs'], true); if (count($req['reqs']) > 0) { foreach ($req['reqs'] as $value) { $req_tmp .= "," . $value; } } $reqid = "[" . $req_tmp . "]"; $sql = "INSERT INTO t_orderreq( T_OrderReqT_OrderHeaderID, T_OrderReqNat_PositionID, T_OrderReqStatus, T_OrderReqT_TestID, T_OrderReqs) VALUES (?,?,?,?,?)"; $prm_orderreq = [ $header_id, $req_id, $req_status, '[]', $reqid ]; $qry = $this->db_smartone->query($sql, $prm_orderreq); if (!$qry) { $result['status'] = false; $result['message'] = 'Terjadi kesalahan saat menyimpan data request'; $result['error_type'] = 'ORDER_REQ_INSERT_ERROR'; $result['error_detail'] = [ 'sql_error' => $this->db_smartone->error(), 'last_query' => $this->db_smartone->last_query() ]; } return $result; } function insert_patient($patient) { $sql = "SELECT fn_numbering('P') as no_reg"; $query = $this->db_smartone->query($sql); if (!$query) { return false; } $rows_no_reg = $query->result_array(); $patient['no_reg'] = $rows_no_reg[0]['no_reg']; $sql = "INSERT INTO m_patient( M_PatientRegisteredByCorporateID, M_PatientNoReg, M_PatientM_TitleID, M_PatientName, M_PatientGender, M_PatientDOB, M_PatientIdentifierValue, M_PatientNIP, M_PatientJob, M_PatientPosisi, M_PatientDivisi, M_PatientLocation, M_PatientDepartement, M_PatientHp, M_PatientEmail, M_PatientAddress, M_PatientAddressRegionalCd, M_PatientAddressRT, M_PatientAddressRW, M_PatientAddressCountry, M_PatientCreated, M_PatientCreatedUserID ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),?)"; $prm = [ $patient['registered_by_corporate_id'], $patient['no_reg'], $patient['m_title_id'], $patient['name'], $patient['gender'], $patient['birthdate'], $patient['nik'], $patient['nip'], $patient['job'], $patient['posisi'], $patient['divisi'], $patient['location'], $patient['departement'], $patient['hp'], $patient['email'], $patient['address'], $patient['address_regional_cd'], $patient['address_rt'], $patient['address_rw'], $patient['address_country'], 666 ]; $query = $this->db_smartone->query($sql, $prm); if (!$query) { return false; } $patient_id = $this->db_smartone->insert_id(); $rtn = [ 'patient_id' => $patient_id, 'no_reg' => $patient['no_reg'] ]; return $rtn; } function insert_preregister($patient, $string_tests, $type_order) { $sql = "INSERT INTO mcu_preregister_patients( Mcu_PreregisterPatientsMgm_McuID, Mcu_PreregisterPatientsCorporateCode, Mcu_PreregisterPatientsPID, Mcu_PreregisterPatientsNIP, Mcu_PreregisterPatientsKTP, Mcu_PreregisterPatientsM_PatientID, Mcu_PreregisterPatientsM_TitleID, Mcu_PreregisterPatientsPatientPrefix, Mcu_PreregisterPatientsPatientName, Mcu_PreregisterPatientsPatientSuffix, Mcu_PreregisterPatientsGender, Mcu_PreregisterPatientsDOB, Mcu_PreregisterPatientsReligion, Mcu_PreregisterPatientsJob, Mcu_PreregisterPatientsEmail, Mcu_PreregisterPatientsHp, Mcu_PreregisterPatientsPosisi, Mcu_PreregisterPatientsDivisi, Mcu_PreregisterPatientsLocation, Mcu_PreregisterPatientsDepartment, Mcu_PreregisterPatientsOrders, Mcu_PreregisterPatientsCreated ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())"; $prm = [ $patient['mgm_mcu_id'], $patient['corporate_code'], $patient['patient_id'], $patient['nip'], $patient['nik'], $patient['patient_id'], $patient['m_title_id'], '', $patient['name'], '', $patient['gender'], $patient['birthdate'], '', $patient['job'], $patient['email'], $patient['hp'], $patient['posisi'], $patient['divisi'], $patient['location'], $patient['departement'], $string_tests ]; $query = $this->db_smartone->query($sql, $prm); if (!$query) { return false; } $preregister_id = $this->db_smartone->insert_id(); return $preregister_id; } function generate_qrcode_booking() { $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $randomCode = ''; for ($i = 0; $i < 5; $i++) { $randomCode .= $characters[rand(0, strlen($characters) - 1)]; } $sql = "SELECT COUNT(*) as total FROM preregister_online WHERE PreregisterOnlineQRCode = ? AND PreregisterOnlineStatus = 'B' AND PreregisterOnlineIsActive = 'Y'"; $query = $this->db_smartone->query($sql, [$randomCode]); if (!$query) { return false; } $rows_total = $query->result_array(); $total = $rows_total[0]['total']; if ($total > 0) { return $this->generate_qrcode_booking(); } return $randomCode; } function preregister_online($preregister_id, $branch_code_lab, $trx_datetime, $diagnose, $fo_note, $patient_id, $patient_corporate_id, $mgm_mcuID, $type_order, $details) { $details = json_encode($details); $rtn = [ 'status' => true, 'message' => 'Success', 'data' => 0, 'query' => '' ]; $qrcode_booking = $this->generate_qrcode_booking(); $sql = "INSERT INTO preregister_online( PreregisterOnlinePreregisterID, PreregisterOnlineQRCode, PreregisterOnlineOrderNumber, PreregisterOnlineBranchCode, PreregisterOnlineTrxDateTime, PreregisterOnlineDiagnose, PreregisterOnlineFoNote, PreregisterOnlineM_PatientID, PreregisterOnlineCorporateID, PreregisterOnlineMgm_McuID, PreregisterOnlineType, PreregisterOnlineCreated, PreregisterOnlineCreatedUserID, PreregisterOnlineJSON ) VALUES (?,?,`fn_numbering_cpone`('OL'),?,?,?,?,?,?,?,?,NOW(),666,?)"; $prm = [ $preregister_id, $qrcode_booking, $branch_code_lab, $trx_datetime, $diagnose, $fo_note, $patient_id, $patient_corporate_id, $mgm_mcuID, $type_order, $details ]; $query = $this->db_smartone->query($sql, $prm); if (!$query) { $error_message = $this->db_smartone->error(); $error_query = $this->db_smartone->last_query(); $rtn['status'] = false; $rtn['message'] = $error_message; $rtn['query'] = $error_query; return $rtn; } $preregister_online_id = $this->db_smartone->insert_id(); $rtn['data'] = $preregister_online_id; return $rtn; } function insert_log_error($sql, $params) { $sql = "INSERT INTO error_log_website( ErrorLogWebsiteCode, ErrorLogWebsiteFnName, ErrorLogWebsiteDescription, ErrorLogWebsiteCreated ) VALUES( ?,?,?,NOW() )"; $query = $this->db_onedev->query($sql, $params); if (!$query) { return false; } return true; } function count_age($birthdate, $date_to = null) { // Jika tanggal acuan tidak disediakan, gunakan hari ini if ($date_to === null) { $date_to = date('Y-m-d'); } // Konversi string tanggal ke objek DateTime $birth_date = new DateTime($birthdate); $to_date = new DateTime($date_to); // Pastikan tanggal lahir tidak di masa depan if ($birth_date > $to_date) { return "Tanggal lahir tidak valid (di masa depan)"; } // Hitung selisih tanggal $interval = $birth_date->diff($to_date); // Ambil tahun, bulan, dan hari dari selisih $years = $interval->y; $months = $interval->m; $days = $interval->d; // Buat string hasil sesuai format $result = ''; // Tambahkan tahun jika ada if ($years > 0) { $result .= $years . ' tahun '; } // Tambahkan bulan jika ada if ($months > 0) { $result .= $months . ' bulan '; } // Tambahkan hari $result .= $days . ' hari'; // Jika tidak ada tahun dan bulan, hanya tampilkan hari if ($years == 0 && $months == 0) { return $days . ' hari'; } return $result; } function check_exist_order($nik, $orders, $trx_datetime) { $sql = "SELECT COUNT(*) as total FROM mcu_preregister_patients JOIN preregister_online ON PreregisterOnlinePreregisterID = Mcu_PreregisterPatientsID AND PreregisterOnlineIsActive = 'Y' WHERE Mcu_PreregisterPatientsKTP = ? AND Mcu_PreregisterPatientsOrders = ? AND Mcu_PreregisterPatientsT_OrderHeaderID = '0' AND Mcu_PreregisterPatientsIsActive = 'Y' AND PreregisterOnlineStatus = 'B' AND PreregisterOnlineTrxDateTime = ? "; $query = $this->db_smartone->query($sql, [$nik, $orders, $trx_datetime]); if (!$query) { return [ 'is_valid' => "N", 'message' => 'Terjadi kesalahan saat memeriksa order', 'query' => $this->db_smartone->last_query(), 'count' => -1 ]; } $rows_total = $query->result_array(); $total = $rows_total[0]['total']; return [ 'is_valid' => "Y", 'message' => $total > 0 ? 'Order sudah ada' : 'Valid', 'count' => $total ]; } private function validateDateTimeNextDay($date, $time) { // Create datetime object from input $inputDateTime = new DateTime($date . ' ' . $time); // Get current datetime $currentDateTime = new DateTime(); // Set minDateTime ke hari berikutnya jam 00:00 $minDateTime = clone $currentDateTime; $minDateTime->modify('+1 day'); $minDateTime->setTime(0, 0, 0); // Set maxDateTime ke 14 hari ke depan $maxDateTime = clone $currentDateTime; $maxDateTime->modify('+14 days'); // Check if the input datetime is within the allowed range if ($inputDateTime < $minDateTime) { return [ 'is_valid' => "N", 'message' => 'Tanggal dan waktu transaksi minimal 1 hari setelah hari ini' ]; } return [ 'is_valid' => "Y", 'message' => 'Valid', 'data' => array('inputdatetime' => $inputDateTime, 'mindatetime' => $minDateTime, 'maxdatetime' => $maxDateTime) ]; } private function validateDateTimeRange($date, $time) { // Create datetime object from input $inputDateTime = new DateTime($date . ' ' . $time); // Get current datetime $currentDateTime = new DateTime(); // Create datetime objects for the boundaries $minDateTime = clone $currentDateTime; $minDateTime->modify('+1 hour'); $maxDateTime = clone $currentDateTime; $maxDateTime->modify('+14 days'); // Check if the input datetime is within the allowed range if ($inputDateTime < $minDateTime) { return [ 'is_valid' => "N", 'message' => 'Tanggal dan waktu transaksi minimal 1 jam dari waktu sekarang' ]; } if ($inputDateTime > $maxDateTime) { return [ 'is_valid' => "N", 'message' => 'Tanggal transaksi tidak boleh lebih dari 14 hari ke depan' ]; } return [ 'is_valid' => "Y", 'message' => 'Valid', 'data' => array('inputdatetime' => $inputDateTime, 'mindatetime' => $minDateTime, 'maxdatetime' => $maxDateTime) ]; } /** * Mendapatkan API key dari header Authorization * * @return string|null API key atau null jika tidak ada */ private function getAuthorizationHeader() { $headers = null; if (isset($_SERVER['Authorization'])) { $headers = trim($_SERVER['Authorization']); } else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { $headers = trim($_SERVER['HTTP_AUTHORIZATION']); } else if (function_exists('apache_request_headers')) { $requestHeaders = apache_request_headers(); $requestHeaders = array_combine( array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders) ); if (isset($requestHeaders['Authorization'])) { $headers = trim($requestHeaders['Authorization']); } } // Format header biasanya "Bearer {token}" if (!empty($headers)) { if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) { return $matches[1]; } } return null; } function validateEmail($email) { // Trim whitespace $email = trim($email); // Cek apakah email kosong if (empty($email)) { return false; } // Cek panjang email (umumnya max 254 karakter) if (strlen($email) > 254) { return false; } // Validasi format email if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { return false; } return true; } /** * Validasi API key * * @param string $apiKey API key untuk divalidasi * @return bool True jika valid, false jika tidak */ private function validateApiKey($apiKey) { if (empty($apiKey)) { return false; } // Contoh implementasi validasi: // 1. Cek token di database // 2. Validasi JWT token // 3. Cek api key statis (hanya untuk contoh sederhana) try { $sql = "SELECT * FROM api_keys WHERE api_key = ? AND is_active = 1 AND expired_at > NOW()"; $prm = [$apiKey]; $query = $this->db_onedev->query($sql, $prm); $data = $query->row_array(); if ($data) { return true; } return false; } catch (Exception $e) { error_log('API key validation error: ' . $e->getMessage()); return false; } } /** * Sanitasi input untuk mencegah SQL injection dan XSS * * @param string $input Input yang akan disanitasi * @return string Input yang sudah disanitasi */ private function sanitizeInput($input) { if (is_string($input)) { // Hapus karakter tidak perlu $input = trim($input); // Hilangkan HTML tags $input = strip_tags($input); // Konversi special characters ke HTML entities $input = htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); return $input; } return $input; } /** * Kirim HTTP response dengan JSON * * @param int $statusCode HTTP status code * @param array $data Data yang akan dikirim sebagai JSON * @return void */ private function sendResponse($statusCode, $data) { http_response_code($statusCode); header('Content-Type: application/json; charset=utf-8'); // Tambahkan header keamanan header('X-Content-Type-Options: nosniff'); header('X-Frame-Options: DENY'); header('X-XSS-Protection: 1; mode=block'); header('Strict-Transport-Security: max-age=31536000; includeSubDomains'); header('Content-Security-Policy: default-src \'self\''); // Set cache control untuk kontrol caching header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); header('Pragma: no-cache'); // Konversi data ke JSON dan kirim echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); exit; } // Fungsi untuk menghasilkan API key baru function generateApiKey($userId, $name, $description, $rateLimit = 100, $expiryDays = 365) { try { $permissions = 'prices:read'; // Generate random token $apiKey = bin2hex(random_bytes(32)); // 64 karakter hex // Set tanggal kadaluarsa (jika ada) $expiredAt = $expiryDays ? date('Y-m-d H:i:s', strtotime("+{$expiryDays} days")) : null; // Convert permissions to JSON if it's an array if (is_array($permissions)) { $permissions = json_encode($permissions); } // Insert ke database $sql = "INSERT INTO api_keys ( user_id, api_key, name, description, permissions, rate_limit, is_active, created_by, expired_at ) VALUES ( ?, ?, ?, ?, ?, ?, 1, ?, ? )"; $prm = [$userId, $apiKey, $name, $description, $permissions, $rateLimit, $userId, $expiredAt]; $query = $this->db_onedev->query($sql, $prm); $data = $query->row_array(); if ($data) { return [ 'id' => $db->lastInsertId(), 'api_key' => $apiKey, 'expired_at' => $expiredAt ]; } return false; } catch (Exception $e) { error_log('Error generating API key: ' . $e->getMessage()); return false; } } // Fungsi untuk menonaktifkan API key function deactivateApiKey($apiKeyId, $userId) { try { $sql = "UPDATE api_keys SET is_active = 0, updated_at = NOW(), updated_by = ? WHERE id = ? AND is_deleted = 0"; $prm = [$userId, $apiKeyId]; $query = $this->db_onedev->query($sql, $prm); $data = $query->row_array(); if ($data) { return true; } return false; } catch (Exception $e) { error_log('Error deactivating API key: ' . $e->getMessage()); return false; } } // Fungsi untuk menghapus API key (soft delete) function deleteApiKey($apiKeyId, $userId) { try { $sql = "UPDATE api_keys SET is_deleted = 1, deleted_at = NOW(), deleted_by = ?, is_active = 0 WHERE id = ? AND is_deleted = 0"; $prm = [$userId, $apiKeyId]; $query = $this->db_onedev->query($sql, $prm); $data = $query->row_array(); if ($data) { return true; } return false; } catch (Exception $e) { error_log('Error deleting API key: ' . $e->getMessage()); return false; } } // Fungsi untuk memvalidasi API key dan cek izin function validateApiKeyWithPermission($apiKey, $requiredPermission) { try { $sql = "SELECT id, user_id, permissions, rate_limit, last_used_at FROM api_keys WHERE api_key = ? AND is_active = 1 AND is_deleted = 0 AND (expired_at IS NULL OR expired_at > NOW())"; $prm = [$apiKey]; $query = $this->db_onedev->query($sql, $prm); $apiKeyData = $query->row_array(); if (!$apiKeyData) { return false; // API key tidak valid atau tidak aktif } // Update last_used_at $sql = "UPDATE api_keys SET last_used_at = NOW() WHERE id = ? AND is_deleted = 0"; $prm = [$apiKeyData['id']]; $query = $this->db_onedev->query($sql, $prm); if (!$query) { $prm_log = ['UPDATE_API_KEY_LAST_USED', 'price/validateApiKeyWithPermission', $this->db_onedev->last_query()]; $log_error = $this->insert_log_error($sql, $prm_log); return false; } // Cek rate limiting (implementasi sederhana) if ($apiKeyData['last_used_at']) { $lastUsed = new DateTime($apiKeyData['last_used_at']); $now = new DateTime(); $diff = $now->getTimestamp() - $lastUsed->getTimestamp(); // Jika terakhir digunakan kurang dari 1 detik yang lalu, dan sudah melebihi rate limit // Ini implementasi sederhana, idealnya gunakan sistem rate limiting yang lebih kompleks if ($diff < 1 && $this->countRecentRequests($apiKeyData['id']) >= $apiKeyData['rate_limit']) { return ['error' => 'rate_limit_exceeded']; } } // Cek permissions jika ada if ($requiredPermission) { $permissions = json_decode($apiKeyData['permissions'], true); // Format permission: {"resource": "action1,action2"} // contoh: {"prices": "read,write"} list($resource, $action) = explode(':', $requiredPermission); if ( !isset($permissions[$resource]) || !in_array($action, explode(',', $permissions[$resource])) ) { return ['error' => 'permission_denied']; } } return $apiKeyData; } catch (Exception $e) { error_log('API key validation error: ' . $e->getMessage()); return false; } } private function validateDate($date) { // Jika input kosong if (empty($date)) { return false; } // Cek format menggunakan regex if (!preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/", $date)) { return false; } // Memecah tanggal menjadi komponen $parts = explode('-', $date); $year = intval($parts[0]); $month = intval($parts[1]); $day = intval($parts[2]); // Validasi tahun tidak boleh lebih besar dari tahun sekarang $currentYear = intval(date('Y')); if ($year > $currentYear) { return false; } // Validasi range dasar if ($year < 1900) { // Minimal tahun 1900 return false; } // Cek bulan if ($month < 1 || $month > 12) { return false; } // Array jumlah hari per bulan $daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Cek tahun kabisat if ($year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0)) { $daysInMonth[1] = 29; } // Cek hari valid untuk bulan tersebut if ($day < 1 || $day > $daysInMonth[$month - 1]) { return false; } return true; } private function validateTime($time) { // If input is empty if (empty($time)) { return false; } // Check format using regex for HH:MM:SS if (preg_match("/^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $time)) { return true; } // Check format using regex for HH:MM if (preg_match("/^([01][0-9]|2[0-3]):([0-5][0-9])$/", $time)) { return true; } // If time doesn't match either format return false; } /** * Memeriksa apakah terdapat nilai nat_tests yang sama antar item dalam array data * dan langsung mengembalikan detail tes yang berkonflik tanpa menampilkan ID * * @param array $data Array data tes yang akan diperiksa * @return array Hasil pengecekan dengan detail konflik */ function check_duplicate_nat_tests($data) { // Array untuk menyimpan nat_tests ID yang sudah ditemui beserta detail tesnya $encountered_nat_tests = []; // Array untuk menyimpan informasi duplikat $duplicate_pairs = []; // Flag untuk menandakan ada duplikat atau tidak $has_duplicates = false; // Iterasi melalui setiap item dalam data foreach ($data as $index => $item) { $test_name = isset($item['test_name']) ? $item['test_name'] : 'Unknown Test'; // Periksa jika nat_tests ada dan dalam bentuk string JSON if (isset($item['nat_tests']) && is_string($item['nat_tests'])) { // Decode string JSON menjadi array $nat_tests_array = json_decode($item['nat_tests'], true); // Jika decode berhasil dan hasilnya array if (is_array($nat_tests_array)) { // Iterasi melalui setiap nat_tests ID dalam item saat ini foreach ($nat_tests_array as $nat_test_id) { // Jika nat_tests ID sudah ada di array encountered_nat_tests, berarti duplikat if (isset($encountered_nat_tests[$nat_test_id])) { $has_duplicates = true; // Buat pasangan nama tes yang berisi duplikat $existing_test = $encountered_nat_tests[$nat_test_id]; $pair_key = ($existing_test < $test_name) ? $existing_test . '|' . $test_name : $test_name . '|' . $existing_test; if (!isset($duplicate_pairs[$pair_key])) { $duplicate_pairs[$pair_key] = [ 'test1' => $existing_test, 'test2' => $test_name ]; } } else { // Jika belum ada, tambahkan ke array encountered_nat_tests $encountered_nat_tests[$nat_test_id] = $test_name; } } } } } // Mengembalikan hasil pengecekan return [ 'is_duplicate' => $has_duplicates, 'duplicate_pairs' => array_values($duplicate_pairs) // Convert to indexed array ]; } /** * Memeriksa apakah terdapat nilai nat_tests yang sama antara array data baru dengan array data yang sudah ada * dan langsung mengembalikan detail tes yang berkonflik tanpa menampilkan ID * * @param array $existing_data Array data tes yang sudah ada * @param array $new_data Array data tes baru yang akan diperiksa * @return array Hasil pengecekan dengan detail konflik */ function check_nat_test_conflicts($existing_data, $new_data) { // Array untuk menyimpan nat_tests ID yang sudah ada beserta detail tesnya $existing_nat_tests = []; // Array untuk menyimpan informasi konflik $conflict_pairs = []; // Flag untuk menandakan ada konflik atau tidak $has_conflicts = false; // Kumpulkan semua nat_tests ID dari data yang sudah ada foreach ($existing_data as $item) { $test_name = isset($item['T_TestName']) ? $item['T_TestName'] : 'Unknown Test'; // Jika nat_tests ada dan dalam bentuk string JSON if (isset($item['nat_tests']) && is_string($item['nat_tests'])) { $nat_tests_array = json_decode($item['nat_tests'], true); if (is_array($nat_tests_array)) { foreach ($nat_tests_array as $nat_test_id) { $existing_nat_tests[$nat_test_id] = $test_name; } } } // Jika nat_test ada dan dalam bentuk array else if (isset($item['nat_test']) && is_array($item['nat_test'])) { foreach ($item['nat_test'] as $nat_test_id) { $existing_nat_tests[$nat_test_id] = $test_name; } } } // Periksa apakah ada nat_tests ID dari data baru yang sudah ada di data yang sudah ada foreach ($new_data as $item) { $test_name = isset($item['T_TestName']) ? $item['T_TestName'] : 'Unknown Test'; // Jika nat_tests ada dan dalam bentuk string JSON if (isset($item['nat_tests']) && is_string($item['nat_tests'])) { $nat_tests_array = json_decode($item['nat_tests'], true); if (is_array($nat_tests_array)) { foreach ($nat_tests_array as $nat_test_id) { if (isset($existing_nat_tests[$nat_test_id])) { $has_conflicts = true; $existing_test = $existing_nat_tests[$nat_test_id]; // Buat pasangan nama tes yang berisi konflik $pair_key = $existing_test . '|' . $test_name; if (!isset($conflict_pairs[$pair_key])) { $conflict_pairs[$pair_key] = [ 'existing_test' => $existing_test, 'new_test' => $test_name ]; } } } } } // Jika nat_test ada dan dalam bentuk array else if (isset($item['nat_test']) && is_array($item['nat_test'])) { foreach ($item['nat_test'] as $nat_test_id) { if (isset($existing_nat_tests[$nat_test_id])) { $has_conflicts = true; $existing_test = $existing_nat_tests[$nat_test_id]; // Buat pasangan nama tes yang berisi konflik $pair_key = $existing_test . '|' . $test_name; if (!isset($conflict_pairs[$pair_key])) { $conflict_pairs[$pair_key] = [ 'existing_test' => $existing_test, 'new_test' => $test_name ]; } } } } } // Mengembalikan hasil pengecekan return [ 'is_conflict' => $has_conflicts, 'conflict_pairs' => array_values($conflict_pairs) // Convert to indexed array ]; } /** * Mendapatkan detail tes berdasarkan nat_tests ID * * @param array $data Array data tes * @param int $nat_test_id ID nat_tests yang dicari * @return array|null Detail tes yang mengandung nat_test_id, null jika tidak ditemukan */ function get_test_by_nat_test_id($data, $nat_test_id) { foreach ($data as $item) { // Jika nat_tests ada dan dalam bentuk string JSON if (isset($item['nat_tests']) && is_string($item['nat_tests'])) { $nat_tests_array = json_decode($item['nat_tests'], true); if (is_array($nat_tests_array) && in_array($nat_test_id, $nat_tests_array)) { return $item; } } // Jika nat_test ada dan dalam bentuk array else if (isset($item['nat_test']) && is_array($item['nat_test']) && in_array($nat_test_id, $item['nat_test'])) { return $item; } } return null; } }