diff --git a/application/controllers/summarydashboard/Sqlgenerator.php b/application/controllers/summarydashboard/Sqlgenerator.php new file mode 100644 index 0000000..1f942ff --- /dev/null +++ b/application/controllers/summarydashboard/Sqlgenerator.php @@ -0,0 +1,577 @@ +db_onedev = $this->load->database("onedev", true); + $this->db_corporate = $this->load->database("cpone_corporate", true); + $this->db_log = $this->load->database("log", true); + } + + // private $passphrase = 'my-key-123'; + private $passphrase = null; + + private $MAGIC = "SQDUMP1\0"; + private $ALG = "AES256GCMHKDFv1"; + private $INFO = "generic_sql_dump/sql"; + + + public function list_mcu_corporate() + { + // Ambil input POST + $db_name = $this->sys_input['db_name'] ?? ''; + + // Validasi + if ($db_name == '') { + echo json_encode([ + "status" => false, + "error" => "db_name is required" + ]); + return; + } + + // Tentukan koneksi database + switch ($db_name) { + case 'cpone_corporate': + $db = $this->db_corporate; + break; + + case 'onedev': + $db = $this->db_onedev; + break; + + case 'log': + $db = $this->db_log; + break; + + default: + echo json_encode([ + "status" => false, + "error" => "Invalid db_name: $db_name" + ]); + return; + } + + // Eksekusi Query + $query = $db->select('Mcu_NumberID, Mcu_NumberMgm_McuID ,Mcu_NumberCorporateName, Mcu_NumberStartDate, Mcu_NumberEndDate') + ->from('mcu_number') + ->order_by('Mcu_NumberID', 'DESC') + ->get(); + + // Cek error DB + $dbError = $db->error(); + if ($dbError['code'] !== 0) { + echo json_encode([ + "status" => false, + "error_code" => $dbError['code'], + "error_message" => $dbError['message'] + ]); + return; + } + + // Response OK + echo json_encode([ + "status" => true, + "data" => $query->result() + ]); + } + + public function get_count_kelainan() + { + $prm = $this->sys_input; + $mgm_mcuid = $prm['Mgm_McuID'] ?? null; + + if (!$mgm_mcuid) { + $this->sys_error("Mgm_McuID required"); + exit; + } + + // Query untuk mengambil semua kelainan yang mungkin DAN menandai yang sudah dipilih + $sql = " + SELECT + all_kelainan.Mcu_KelainanID, + all_kelainan.Mcu_KelainanName, + all_kelainan.total_patient, + CASE + WHEN ks.Mcu_KelainanID IS NOT NULL THEN 1 + ELSE 0 + END AS is_selected + FROM ( + -- Subquery untuk menghitung total pasien per kelainan + SELECT + kd.Mcu_KelainanID, + kd.Mcu_KelainanName, + COUNT(DISTINCT oh.T_OrderHeaderM_PatientID) AS total_patient + FROM cpone_corporate.kelainan_details kd + JOIN cpone.t_orderheader oh + ON kd.T_OrderHeaderID = oh.T_OrderHeaderID + WHERE oh.T_OrderHeaderMgm_McuID = ? + AND oh.T_OrderHeaderIsActive = 'Y' + GROUP BY kd.Mcu_KelainanID, kd.Mcu_KelainanName + ) AS all_kelainan + LEFT JOIN cpone_corporate.kelainan_summary ks + ON all_kelainan.Mcu_KelainanID = ks.Mcu_KelainanID + AND ks.Mcu_KelainanMgm_McuID = ? + ORDER BY all_kelainan.total_patient DESC + "; + + // Parameter untuk query (digunakan dua kali) + $params = [$mgm_mcuid, $mgm_mcuid]; + $query = $this->db->query($sql, $params); + + if (!$query) { + $this->sys_error_db("get count kelainan", $this->db); + exit; + } + + $result = $query->result_array(); + + $this->sys_ok([ + "mgm_mcuid" => $mgm_mcuid, + "data" => $result + ]); + exit; + } + + function save_kelainan_selection() + { + $prm = $this->sys_input; + + $mgm_mcu_id = isset($prm['mgm_mcu_id']) ? intval($prm['mgm_mcu_id']) : 0; + $selected_kelainan = isset($prm['selected_kelainan']) ? $prm['selected_kelainan'] : []; + + if ($mgm_mcu_id <= 0) { + $this->sys_error("mgm_mcu_id tidak valid"); + exit; + } + + // Validasi frontend sudah cukup ketat, namun validasi backend tetap penting sebagai pengaman. + // Logika validasi di sini memastikan jumlah yang dipilih tidak kurang dari yang seharusnya. + $sql_total = " + SELECT COUNT(DISTINCT kd.Mcu_KelainanID) AS total_available + FROM cpone_corporate.kelainan_details kd + JOIN cpone.t_orderheader oh ON kd.T_OrderHeaderID = oh.T_OrderHeaderID + WHERE oh.T_OrderHeaderMgm_McuID = ? AND oh.T_OrderHeaderIsActive = 'Y' + "; + $query_total = $this->db->query($sql_total, [$mgm_mcu_id]); + $total_available = $query_total->row()->total_available; + + $total_selected = count($selected_kelainan); + + if ($total_available >= 10) { + if ($total_selected != 10) { + $this->sys_error("Harap pilih tepat 10 kelainan."); + exit; + } + } else { + if ($total_selected != $total_available) { + $this->sys_error("Harap pilih semua {$total_available} kelainan yang tersedia."); + exit; + } + } + + + + // Wajib gunakan DB corporate karena tabel kelainan_summary ada di cpone_corporate + $db = $this->db_corporate; + + // Mulai transaksi + $db->trans_begin(); + + // Hapus data sebelumnya untuk MCU ini + $sql_delete = "DELETE FROM kelainan_summary WHERE Mcu_KelainanMgm_McuID = ?"; + $db->query($sql_delete, [$mgm_mcu_id]); + + // Query insert + $sql_insert = " + INSERT INTO kelainan_summary + (Mcu_KelainanID, Mcu_KelainanMgm_McuID, Mcu_KelainanName) + VALUES (?, ?, ?) + "; + + foreach ($selected_kelainan as $item) { + + if (!isset($item["id"]) || !isset($item["name"])) { + $db->trans_rollback(); + $this->sys_error("Format data kelainan tidak valid"); + exit; + } + + $db->query($sql_insert, [ + $item["id"], + $mgm_mcu_id, + $item["name"] + ]); + } + + if ($db->trans_status() === FALSE) { + $err = $db->error(); + $db->trans_rollback(); + $this->sys_error("Gagal menyimpan data. DB Error: " . $err['message']); + exit; + } + + $db->trans_commit(); + + $this->sys_ok([ + "message" => "Kelainan berhasil disimpan", + "total_saved" => count($selected_kelainan), + "saved_data" => $selected_kelainan + ]); + } + + public function get_kelainan_selected() + { + $prm = $this->sys_input; + + $mgm_mcu_id = isset($prm['mgm_mcu_id']) ? intval($prm['mgm_mcu_id']) : 0; + + if ($mgm_mcu_id <= 0) { + $this->sys_error("mgm_mcu_id tidak valid"); + return; + } + + // Ambil kelainan yang sudah dipilih user sebelumnya + $sql = " + SELECT + Mcu_KelainanID AS id, + Mcu_KelainanName AS name + FROM kelainan_summary + WHERE Mcu_KelainanMgm_McuID = ? + ORDER BY Mcu_KelainanID + "; + + $query = $this->db_corporate->query($sql, [$mgm_mcu_id]); + + if (!$query) { + $this->sys_error_db("get kelainan selected", $this->db_corporate); + return; + } + + $this->sys_ok([ + "mgm_mcu_id" => $mgm_mcu_id, + "selected" => $query->result_array() + ]); + } + + + private function generate_sql_dump($db_name) + { + // Pilih koneksi + switch ($db_name) { + case 'onedev': $db = $this->db_onedev; break; + case 'cpone_corporate': $db = $this->db_corporate; break; + case 'log': $db = $this->db_log; break; + default: + throw new Exception("Invalid db_name: {$db_name}"); + } + + $sql_dump = ""; + $tables = $db->query("SHOW TABLES")->result_array(); + $table_key = "Tables_in_" . $db_name; + + foreach ($tables as $tbl) { + $table_name = $tbl[$table_key]; + + // Struktur tabel + $create_row = $db->query("SHOW CREATE TABLE `{$table_name}`")->row_array(); + $sql_dump .= $create_row['Create Table'] . ";\n\n"; + + // Data tabel + $rows = $db->query("SELECT * FROM `{$table_name}`")->result_array(); + foreach ($rows as $row) { + $columns = array_keys($row); + $values = array_map(function ($val) use ($db) { + return is_null($val) ? "NULL" : "'" . $db->escape_str($val) . "'"; + }, array_values($row)); + + $sql_dump .= "INSERT INTO `{$table_name}` (`" . implode('`,`', $columns) . + "`) VALUES(" . implode(",", $values) . ");\n"; + } + + $sql_dump .= "\n"; + } + + return $sql_dump . "COMMIT;\n"; + } + + public function encrypt_and_download(string $sql, string $filename = "dump.dat") + { + // --- generate material --- + $salt = random_bytes(16); + $nonce = random_bytes(12); + $key = hash_hkdf('sha256', $this->passphrase, 32, $this->INFO, $salt); + + $tag = null; + $ciphertext = openssl_encrypt( + $sql, + 'aes-256-gcm', + $key, + OPENSSL_RAW_DATA, + $nonce, + $tag + ); + + if ($ciphertext === false) { + show_error('Encryption failed', 500); + return; + } + + // --- format blob seperti modul Dl_sqlite --- + $blob = + $this->MAGIC . + chr(strlen($this->ALG)) . $this->ALG . + chr(strlen($salt)) . $salt . + chr(strlen($nonce)) . $nonce . + chr(strlen($tag)) . $tag . + $ciphertext; + + // --- stream download .dat --- + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename="' . $filename . '"'); + header('Content-Length: ' . strlen($blob)); + header('Cache-Control: no-cache, no-store, must-revalidate'); + header('Pragma: no-cache'); + header('Expires: 0'); + + echo $blob; + exit; + } + + public function download() + { + // --- Ambil parameter dari GET --- + $db_name = $this->input->get('db_name'); + $mcu_id = intval($this->input->get('Mgm_McuID')); + + if (!$db_name) { + show_error("db_name is required", 400); + return; + } + + if ($mcu_id <= 0) { + show_error("Mgm_McuID is required", 400); + return; + } + + // --- Ambil passphrase dari DB corporate --- + try { + $this->passphrase = $this->get_passphrase_from_mcu($mcu_id); + } catch (Exception $e) { + show_error($e->getMessage(), 500); + return; + } + + // --- Generate SQL dump --- + $sql = $this->generate_sql_dump($db_name); + + // --- Encrypt dan kirim file download --- + $this->encrypt_and_download( + $sql, + "dump_{$db_name}_{$mcu_id}.dat" + ); + } + + function show_key(): void + { + $this->sys_ok([ + "passphrase" => $this->passphrase, + "info" => $this->INFO, + "algorithm" => $this->ALG, + "note" => "The final key is derived using HKDF-SHA256 with the passphrase, info, and a random salt generated for each download." + ]); + } + + function truncate_corporate_tables() + { + // Untuk keamanan, endpoint ini memerlukan parameter konfirmasi. + $prm = $this->sys_input; + if (!isset($prm['confirm_truncate']) || $prm['confirm_truncate'] !== true) { + $this->sys_error("Operasi TRUNCATE memerlukan konfirmasi. Kirim { \"confirm_truncate\": true } untuk melanjutkan."); + return; + } + + $tables_to_truncate = [ + 'kelainan_details', + 'kelainan_summary', + 'mcu_result_all', + 'mcu_number' + ]; + + $truncated_tables = []; + $errors = []; + + foreach ($tables_to_truncate as $table) { + if ($this->db_corporate->table_exists($table)) { + if ($this->db_corporate->truncate($table)) { + $truncated_tables[] = $table; + } else { + $errors[] = "Gagal melakukan TRUNCATE pada tabel: {$table}"; + } + } + } + + if (!empty($errors)) { + $this->sys_error("Terjadi kesalahan saat TRUNCATE tabel.", $errors); + return; + } + + $this->sys_ok([ + "message" => "Semua tabel yang relevan berhasil di-TRUNCATE.", + "truncated_tables" => $truncated_tables + ]); + } + + private function generateRandomCode($length = 6) + { + $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + $code = ''; + + for ($i = 0; $i < $length; $i++) { + $code .= $chars[random_int(0, strlen($chars) - 1)]; + } + + return $code; + } + + public function create_encrypt_key() + { + // --- Ambil input JSON --- + $prm = json_decode($this->input->raw_input_stream, true); + $mcu_id = intval($prm['Mgm_McuID'] ?? 0); + + if ($mcu_id <= 0) { + $this->sys_error("Mgm_McuID wajib diisi"); + return; + } + + // Jika tidak ada session user, gunakan default 0 + $user_id = 0; + + // --- 1. Nonaktifkan key lama --- + $this->db + ->where('Mgm_McuEncryptMgm_McuID', $mcu_id) + ->update('mgm_mcuencrypt', [ + 'Mgm_McuEncryptIsActive' => 'N' + ]); + + // Reset builder biar query berikutnya bersih + $this->db->reset_query(); + + // --- 2. Generate kode unik --- + do { + $code = $this->generateRandomCode(6); + + $query = $this->db + ->select('Mgm_McuEncryptID') + ->where('Mgm_McuEncryptCode', $code) + ->get('mgm_mcuencrypt'); + + if (!$query) { + $err = $this->db->error(); + $this->sys_error("DB Error: " . $err['message']); + return; + } + + $exists = $query->num_rows(); + } while ($exists > 0); + + // --- 3. Insert key baru --- + $insert = [ + 'Mgm_McuEncryptMgm_McuID' => $mcu_id, + 'Mgm_McuEncryptCode' => $code, + 'Mgm_McuEncryptIsActive' => 'Y', + 'Mgm_McuEncryptCreated' => date('Y-m-d H:i:s'), + 'Mgm_McuEncryptUserID' => $user_id // FIX: tidak pakai session + ]; + + $this->db->insert('mgm_mcuencrypt', $insert); + + if ($this->db->affected_rows() <= 0) { + $err = $this->db->error(); + $this->sys_error("Gagal insert key baru: " . $err['message']); + return; + } + + // --- 4. Return response --- + $this->sys_ok([ + "message" => "Key baru berhasil dibuat", + "Mgm_McuID" => $mcu_id, + "new_key" => $code + ]); + } + + public function get_active_encrypt_key() + { + // --- Ambil input JSON --- + $prm = json_decode($this->input->raw_input_stream, true); + $mcu_id = intval($prm['Mgm_McuID'] ?? 0); + + if ($mcu_id <= 0) { + $this->sys_error("Mgm_McuID wajib diisi"); + return; + } + + // --- Query untuk mendapatkan key aktif --- + $query = $this->db + ->select('Mgm_McuEncryptCode') + ->from('mgm_mcuencrypt') + ->where('Mgm_McuEncryptMgm_McuID', $mcu_id) + ->where('Mgm_McuEncryptIsActive', 'Y') + ->order_by('Mgm_McuEncryptID', 'DESC') + ->limit(1) + ->get(); + + if (!$query) { + $err = $this->db->error(); + $this->sys_error("DB Error: " . $err['message']); + return; + } + + $result = $query->row_array(); + + if (!$result) { + $this->sys_error("Tidak ada key enkripsi aktif yang ditemukan untuk MCU ID: " . $mcu_id); + return; + } + + // --- Return response --- + $this->sys_ok([ + "message" => "Key aktif berhasil ditemukan", + "Mgm_McuID" => $mcu_id, + "active_key" => $result['Mgm_McuEncryptCode'] + ]); + } + + + private function get_passphrase_from_mcu($mcu_id) + { + $query = $this->db + ->select('Mgm_McuEncryptCode') + ->from('mgm_mcuencrypt') + ->where('Mgm_McuEncryptMgm_McuID', $mcu_id) + ->where('Mgm_McuEncryptIsActive', 'Y') + ->order_by('Mgm_McuEncryptID', 'DESC') + ->limit(1) + ->get(); + + if (!$query) { + $err = $this->db->error(); + throw new Exception("DB error: " . $err['message']); + } + + $row = $query->row_array(); + if (!$row) { + throw new Exception("Active encryption key not found for Mgm_McuID: {$mcu_id}"); + } + + return $row['Mgm_McuEncryptCode']; + } + + + +} + + diff --git a/application/controllers/summarydashboard/sql_requests.http b/application/controllers/summarydashboard/sql_requests.http new file mode 100644 index 0000000..ab8157c --- /dev/null +++ b/application/controllers/summarydashboard/sql_requests.http @@ -0,0 +1,115 @@ +@baseUrl = https://devcpone.aplikasi.web.id/one-api/summarymcu +@contentType = application/json + +### ============================================================ +### LIST CORPORATE +### ============================================================ + +POST {{baseUrl}}/sqlgenerator/list_mcu_corporate +Content-Type: application/json + +{ + "db_name": "cpone_corporate" +} + + +### ============================================================ +### LIST PASIEN +### ============================================================ + +### List Pasien MCU by Kelainan +# Mengelompokkan pasien berdasarkan kelainan dari tabel kelainan_details +# dan menghitung total pasien untuk setiap kelainan. +### LIST PASIEN MCU +POST {{baseUrl}}/sqlgenerator/list_pasien_mcu +Content-Type: application/json + +{ + +} + +### +POST {{baseUrl}}/sqlgenerator/get_count_kelainan +Content-Type: application/json + +{ + "Mgm_McuID": 151 +} + + + +### +POST {{baseUrl}}/sqlgenerator/total_pasien_mcu +Content-Type: application/json + +{} + +### +{{baseUrl}}/sqlgenerator/save_kelainan_selection +Content-Type: {{contentType}} + +{ + "mgm_mcu_id": 151, + "selected_kelainan": [ + { "id": 80, "name": "Peningkatan profil lemak" }, + { "id": 133, "name": "Peningkatan fungsi hati" }, + { "id": 33, "name": "Karang Gigi" }, + { "id": 214, "name": "Miopia O" }, + { "id": 180, "name": "Presbiopia ODS" }, + { "id": 60, "name": "Leukositosis" }, + { "id": 4, "name": "Obesitas tipe 2" }, + { "id": 2, "name": "Overweight" }, + { "id": 134, "name": "Gangguan fungsi hati" }, + { "id": 227, "name": "Hipertensi stage 1" } + ] +} + +### ============================================================ +### DATABASE DUMP +### ============================================================ + +### ============================================================ +### DATABASE TRUNCATE +### ============================================================ + +### Truncate tabel-tabel corporate +POST {{baseUrl}}/sqlgenerator/truncate_corporate_tables +Content-Type: {{contentType}} + +{ + "confirm_truncate": true +} + +### Enkripsi dan unduh database sebagai file .dat +GET {{baseUrl}}/sqlgenerator/download +Content-Type: application/json + +{ + "db_name": "cpone_corporate", + "Mgm_McuID": 151 +} + +## +### Tampilkan komponen kunci enkripsi +POST {{baseUrl}}/sqlgenerator/show_key +Content-Type: application/json + +{ + "Mgm_McuID": 151 +} + +#### +POST {{baseUrl}}/sqlgenerator/create_encrypt_key +Content-Type: application/json + +{ + "Mgm_McuID": 151 +} + +#### +POST {{baseUrl}}/sqlgenerator/get_active_encrypt_key +Content-Type: application/json + +{ + "Mgm_McuID": 151 +} \ No newline at end of file diff --git a/application/controllers/summarydashboard/try_out.http b/application/controllers/summarydashboard/try_out.http new file mode 100644 index 0000000..76c7f7a --- /dev/null +++ b/application/controllers/summarydashboard/try_out.http @@ -0,0 +1,389 @@ +### Variables +@baseUrl = https://devcpone.aplikasi.web.id/one-api/summarymcu/ +@contentType = application/json + +### ============================================================ +### SETUP & TABLE GENERATION +### ============================================================ + +### 1. Generate Table Setup +# Creates mcu_number record and generates table name +POST {{baseUrl}}/generatedata/generate_table_setup +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1403 +} + +### ============================================================ +### KELAINAN DATA GENERATION +### ============================================================ + +### 2. Generate Kelainan Lab +# Generates lab anomaly details data +POST {{baseUrl}}/generatedata/generate_kelainan_lab +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 2 +} + +### 3. Generate Kelainan Non-Lab +# Generates non-lab anomaly details data +POST {{baseUrl}}/generatedata/generate_kelainan_nonlab +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 2 +} + +### 4. Generate Kelainan Fisik +# Generates physical anomaly details data +POST {{baseUrl}}/generatedata/generate_kelainan_fisik +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 5. Summary Kelainan Sepuluh +# Generates summary of top 10 anomalies +POST {{baseUrl}}/generatedata/summary_kelainan_sepuluh +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### ============================================================ +### MCU RESULTS GENERATION +### ============================================================ + +### 6. Generate All Results +# Generates mcu_result_all table data +POST {{baseUrl}}/generatedata/generate_all_results +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 7. Generate Result MCU Lab +# Generates lab results for all orders in MCU +POST {{baseUrl}}/generatedata/generate_result_mcu_lab +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 8. Generate Result MCU Non-Lab +# Generates non-lab results +POST {{baseUrl}}/generatedata/generate_result_mcu_nonlab +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 9. Generate Result MCU Kenal Warna +# Generates color recognition test results +POST {{baseUrl}}/generatedata/generate_result_mcu_kenal_warna +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 10. Generate Result MCU Visus +# Generates visual acuity test results +POST {{baseUrl}}/generatedata/generate_result_mcu_visus +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 11. Generate Result MCU Status Gizi +# Generates nutritional status results +POST {{baseUrl}}/generatedata/generate_result_mcu_status_gizi +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 12. Generate Result MCU Body Fat Monitoring +# Generates body fat monitoring results +POST {{baseUrl}}/generatedata/generate_result_mcu_bodyfatmonitoring +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 13. Generate Result MCU Fisik +# Generates physical examination results +POST {{baseUrl}}/generatedata/generate_result_mcu_fisik +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### 14. Generate Result Lab (Specific Order) +# Generates lab results for specific order +##POST {{baseUrl}}/generatedata/generate_result_lab +#Content-Type: {{contentType}} + +#{ +# "T_OrderHeaderID": 12345, +# "T_OrderHeaderLabNumber": "LAB001" +#} + + + +### ============================================================ +### COMPLETE WORKFLOW EXAMPLE +### ============================================================ + +### SCENARIO 1: Setup New MCU Project (Complete Flow) +# Step 1: Generate table setup +POST {{baseUrl}}/generatedata/generate_table_setup +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### +# Step 2: Generate lab anomalies +POST {{baseUrl}}/generatedata/generate_kelainan_lab +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### +# Step 3: Generate non-lab anomalies +POST {{baseUrl}}/generatedata/generate_kelainan_nonlab +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### +# Step 4: Generate physical anomalies +POST {{baseUrl}}/generatedata/generate_kelainan_fisik +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### +# Step 5: Generate summary +POST {{baseUrl}}/generatedata/summary_kelainan_sepuluh +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### +# Step 6: Export to SQLite +POST {{baseUrl}}/generatedata/generate_sqlite_by_mgm_mcuid +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + + +### ============================================================ +### FISIK TEMPLATE MAP FUNCTIONS +### Step-by-step workflow for template mapping +### ============================================================ + +### STEP 1: List Active Fisik Templates (Optional) +# View all active templates +POST {{baseUrl}}/generatedata/list_active_fisik_templates +Content-Type: {{contentType}} + +{} + +### STEP 2: Get Fisik Template Detail (Optional) +# View detail of specific template with parsed JSON +POST {{baseUrl}}/generatedata/get_fisik_template_detail +Content-Type: {{contentType}} + +{ + "FisikTemplateCode": "RI00" +} + +### STEP 3: Create Fisik Template Map Table (Once Only) +# Creates the fisik_template_map table +POST {{baseUrl}}/generatedata/create_fisik_template_map_table +Content-Type: {{contentType}} + +{} + +### STEP 4a: Generate Fisik Template Map (Full Generate) +# Extract & save mapping for ALL active templates +# Note: Truncates all old data, inserts all new data +POST {{baseUrl}}/generatedata/generate_fisik_template_map +Content-Type: {{contentType}} + +{} + +### STEP 4b: Generate Fisik Template Map By Code (Partial Update) +# Extract & update mapping for ONE template only +# Use when only one template changed +POST {{baseUrl}}/generatedata/generate_fisik_template_map_by_code +Content-Type: {{contentType}} + +{ + "FisikTemplateCode": "RI00" +} + +### STEP 5a: Get Fisik Template Map +# Query mapping data with optional filters +POST {{baseUrl}}/generatedata/get_fisik_template_map +Content-Type: {{contentType}} + +{ + "FisikTemplateCode": "RI00", + "level": 2 +} + +### STEP 5a-1: Get All Fisik Template Map Data +POST {{baseUrl}}/generatedata/get_fisik_template_map +Content-Type: {{contentType}} + +{} + +### STEP 5a-2: Get By Template Code Only +POST {{baseUrl}}/generatedata/get_fisik_template_map +Content-Type: {{contentType}} + +{ + "FisikTemplateCode": "RI00" +} + +### STEP 5a-3: Get By Level Only +POST {{baseUrl}}/generatedata/get_fisik_template_map +Content-Type: {{contentType}} + +{ + "level": 2 +} + +### STEP 5b: Search Fisik Template Map +# Search by id_code or label (LIKE search) +POST {{baseUrl}}/generatedata/search_fisik_template_map +Content-Type: {{contentType}} + +{ + "keyword": "perut" +} + +### ============================================================ +### SQLITE EXPORT +### ============================================================ + +### 15. Generate SQLite by Mgm_McuID +# Exports kelainan_details, kelainan_summary, and mcu_number to SQLite file +POST {{baseUrl}}/generatedata/generate_sqlite_by_mgm_mcuid +Content-Type: {{contentType}} + +{ + "Mgm_McuID": 1 +} + +### ============================================================ +### SCENARIO 2: Fisik Template Setup (First Time) +### ============================================================ + +### +# Step 1: Create the mapping table (once) +POST {{baseUrl}}/generatedata/create_fisik_template_map_table +Content-Type: {{contentType}} + +{} + +### +# Step 2: Generate all template mappings +POST {{baseUrl}}/generatedata/generate_fisik_template_map +Content-Type: {{contentType}} + +{} + +### +# Step 3: Query the generated mappings +POST {{baseUrl}}/generatedata/get_fisik_template_map +Content-Type: {{contentType}} + +{} + +### ============================================================ +### SCENARIO 3: Update Single Template (Maintenance) +### ============================================================ + +### +# Update mapping for specific template only +POST {{baseUrl}}/generatedata/generate_fisik_template_map_by_code +Content-Type: {{contentType}} + +{ + "FisikTemplateCode": "RI00" +} + +### +# Verify the updated mapping +POST {{baseUrl}}/generatedata/get_fisik_template_map +Content-Type: {{contentType}} + +{ + "FisikTemplateCode": "RI00" +} + +### ============================================================ +### NOTES & TIPS +### ============================================================ + +# 1. Update @baseUrl variable at the top with your actual server URL +# 2. Replace Mgm_McuID with actual MCU ID from your database +# 3. Use ### to separate requests +# 4. Click "Send Request" above each request to execute +# 5. For CodeIgniter, ensure index.php is in URL if not using URL rewriting +# Example: http://localhost/project/index.php/generatedata/function_name +# 6. Check commented documentation in controller for detailed workflow +# 7. Some functions depend on previous steps (e.g., generate_kelainan_* requires generate_table_setup first) +# 8. SQLite export creates file in root directory: mcu_{TableName}.sqlite + +### ============================================================ +### ERROR TESTING +### ============================================================ + +### Test Missing Parameter +POST {{baseUrl}}/generatedata/generate_table_setup +Content-Type: {{contentType}} + +{} + +### Test Invalid Template Code +POST {{baseUrl}}/generatedata/get_fisik_template_detail +Content-Type: {{contentType}} + +{ + "FisikTemplateCode": "INVALID_CODE" +} + +### Test Missing Keyword +POST {{baseUrl}}/generatedata/search_fisik_template_map +Content-Type: {{contentType}} + +{} + diff --git a/application/controllers/v1/su/Test.php b/application/controllers/v1/su/Test.php index de7850c..b37f64e 100644 --- a/application/controllers/v1/su/Test.php +++ b/application/controllers/v1/su/Test.php @@ -8,15 +8,35 @@ class Test extends MY_Controller echo "Transaction API"; } - public function __construct() - { - parent::__construct(); - $this->db_onedev = $this->load->database("onedev", true); - $this->db_log = $this->load->database("log", true); - $this->load->helper(array('form', 'url')); - } - /** - * Generic POST request function + public function __construct() + { + parent::__construct(); + $this->db_onedev = $this->load->database("onedev", true); + $this->db_log = $this->load->database("log", true); + $this->load->helper(array('form', 'url')); + } + + public function test_generate_dashboard_file() + { + $prm = $this->sys_input; + $mgmMcuID = isset($prm['Mgm_McuID']) ? intval($prm['Mgm_McuID']) : 0; + $publishedID = isset($prm['Published_McuDasboardID']) ? intval($prm['Published_McuDasboardID']) : 0; + + $this->load->library('Mcudashboard'); + $rtn = $this->mcudashboard->generate_dashboard_files($mgmMcuID, $publishedID); + if (!$rtn[0]) { + $this->sys_error($rtn[1]); + exit; + } + + $this->sys_ok(array( + "total" => count($rtn[1]), + "records" => $rtn[1] + )); + exit; + } + /** + * Generic POST request function * @param string $url API endpoint URL * @param array $data Request payload * @param array $headers Custom headers (optional) diff --git a/scripts/sql/2026-04-29_alter_published_mcu_dashboard_add_file_url.sql b/scripts/sql/2026-04-29_alter_published_mcu_dashboard_add_file_url.sql new file mode 100644 index 0000000..15b6d00 --- /dev/null +++ b/scripts/sql/2026-04-29_alter_published_mcu_dashboard_add_file_url.sql @@ -0,0 +1,2 @@ +ALTER TABLE published_mcu_dashboard +ADD COLUMN IF NOT EXISTS Published_McuDasboardFileUrl VARCHAR(255) NULL AFTER Published_McuDasboardStatus;