db_smartone = $this->load->database("onedev", true); $this->db_onedev = $this->load->database("onedev", true); $this->load->library('ibl_encryptor'); } private function payment_amount_net($payment) { $left = floatval($payment['leftvalue'] ?? 0); $right = floatval($payment['rightvalue'] ?? 0); $code = strtoupper($payment['code'] ?? ''); if ($code === 'CASH') { return max(0, $left - $right); } return max(0, $left); } private function build_zero_payment($payment) { $payment['chex'] = false; $payment['leftvalue'] = 0; $payment['rightvalue'] = 0; return $payment; } private function get_selected_lookup_id($value) { if (is_array($value)) { return intval($value['id'] ?? 0); } return 0; } private function split_payments_for_klinik($payments, $clinic_amount) { $remaining_clinic = max(0, floatval($clinic_amount)); $clinic_payments = []; $ibl_payments = []; foreach ($payments as $payment) { $code = strtoupper($payment['code'] ?? ''); $net_amount = $this->payment_amount_net($payment); $allocated = min($remaining_clinic, $net_amount); $clinic_payment = $this->build_zero_payment($payment); $ibl_payment = $payment; if ($allocated > 0) { $clinic_payment['chex'] = true; if ($code === 'CASH') { $clinic_payment['leftvalue'] = $allocated; $clinic_payment['rightvalue'] = 0; $ibl_payment['leftvalue'] = max(0, floatval($payment['leftvalue']) - $allocated); $ibl_payment['chex'] = ($this->payment_amount_net($ibl_payment) > 0); } else { $clinic_payment['leftvalue'] = $allocated; $ibl_payment['leftvalue'] = max(0, floatval($payment['leftvalue']) - $allocated); $ibl_payment['chex'] = (floatval($ibl_payment['leftvalue']) > 0); } $remaining_clinic -= $allocated; } else { $ibl_payment['chex'] = ($net_amount > 0) ? !empty($payment['chex']) : false; } $clinic_payments[] = $clinic_payment; $ibl_payments[] = $ibl_payment; } return [ 'clinic_payments' => $clinic_payments, 'ibl_payments' => $ibl_payments, 'allocated_total' => max(0, floatval($clinic_amount) - $remaining_clinic) ]; } private function get_order_klinik_outstanding($order_klinik_id) { $sql = "SELECT o.orderID, o.orderTotal, IFNULL(SUM(CASE WHEN p.PaymentIsActive = 'Y' THEN p.PaymentTotal ELSE 0 END), 0) AS paid_total FROM one_klinik.`order` o LEFT JOIN one_klinik.`payment` p ON p.PaymentOrderID = o.orderID WHERE o.orderID = ? GROUP BY o.orderID, o.orderTotal LIMIT 1"; $query = $this->db_onedev->query($sql, [$order_klinik_id]); if (!$query) { return [false, "Gagal mengambil data order klinik"]; } $row = $query->row_array(); if (!$row) { return [false, "Order klinik tidak ditemukan"]; } $outstanding = max(0, floatval($row['orderTotal']) - floatval($row['paid_total'])); $row['outstanding_total'] = $outstanding; return [true, $row]; } private function save_payment_klinik($orderid, $payments, $xuserid) { $sql = "INSERT INTO one_klinik.`payment`(PaymentOrderID,PaymentDate,PaymentCreated,PaymentM_UserID) VALUES (?,CURDATE(),NOW(),?)"; $query = $this->db_onedev->query($sql, [$orderid, $xuserid]); if (!$query) { return [false, "payment klinik insert"]; } $headerid = $this->db_onedev->insert_id(); foreach ($payments as $v) { if (empty($v['chex'])) { continue; } $actual = 0; $change = 0; $amount = floatval($v['leftvalue'] ?? 0); if (($v['code'] ?? '') == 'CASH') { $actual = floatval($v['leftvalue'] ?? 0); $change = floatval($v['rightvalue'] ?? 0); $amount = ($actual > 0) ? ($actual - $change) : $actual; $sql = "INSERT INTO one_klinik.`paymentdetail`( PaymentDetailPaymentID, PaymentDetailM_PaymentTypeID, PaymentDetailAmount, PaymentDetailActual, PaymentDetailChange, PaymentDetailCreated, PaymentDetailLastUpdated, PaymentDetailUserID ) VALUES (?, ?, ?, ?, ?, now(), now(), ?)"; $query = $this->db_onedev->query($sql, [ $headerid, $v['id'], $amount, $actual, $change, $xuserid ]); if (!$query) { return [false, "payment klinik detail cash insert"]; } } else { $selected_card = 0; $selected_edc = 0; if (($v['code'] ?? '') == 'DEBIT' || ($v['code'] ?? '') == 'CREDIT' || ($v['code'] ?? '') == 'TRANSFER') { $selected_card = $this->get_selected_lookup_id($v['selected_card'] ?? null); $selected_edc = $this->get_selected_lookup_id($v['selected_edc'] ?? null); if (($v['code'] ?? '') == 'TRANSFER') { $selected_edc = $this->get_selected_lookup_id($v['selected_account'] ?? null); } } $sql = "INSERT INTO one_klinik.`paymentdetail`( PaymentDetailPaymentID, PaymentDetailM_PaymentTypeID, PaymentDetailAmount, PaymentDetailActual, PaymentDetailChange, PaymentDetailCardNat_BankID, PaymentDetailEDCNat_BankID, PaymentDetailM_BankAccountID, PaymentDetailCreated, PaymentDetailLastUpdated, PaymentDetailUserID ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, now(), now(), ?)"; $query = $this->db_onedev->query($sql, [ $headerid, $v['id'], $amount, 0, 0, $selected_card, 0, $selected_edc, $xuserid ]); if (!$query) { return [false, "payment klinik detail non cash insert"]; } } } $sql = "SELECT SUM(PaymentDetailAmount) as total FROM one_klinik.`paymentdetail` WHERE PaymentDetailPaymentID = ? AND PaymentDetailIsActive = 'Y'"; $total_paid = floatval($this->db_onedev->query($sql, [$headerid])->row()->total ?? 0); $sql = "UPDATE one_klinik.`payment` SET PaymentTotal = ? WHERE PaymentID = ?"; $this->db_onedev->query($sql, [$total_paid, $headerid]); $sql = "SELECT SUM(PaymentTotal) as paid, orderTotal as total FROM one_klinik.`payment` JOIN one_klinik.`order` ON orderID = PaymentOrderID WHERE PaymentOrderID = ? AND PaymentIsActive = 'Y'"; $xtotal_all_paid = $this->db_onedev->query($sql, [$orderid])->row_array(); if ($xtotal_all_paid && floatval($xtotal_all_paid['paid']) >= floatval($xtotal_all_paid['total'])) { $sql = "UPDATE one_klinik.`order` SET orderIsLunas = 'Y' WHERE orderID = ?"; $this->db_onedev->query($sql, [$orderid]); } $xdata = $this->db_onedev->query( "SELECT PaymentID as idx, PaymentNumber as numberx FROM one_klinik.payment WHERE PaymentID = ?", [$headerid] )->row(); return [true, ['payment_id' => $headerid, 'payment_total' => $total_paid, 'data' => $xdata]]; } public function get_order() { $prm = $this->sys_input; $rst = ["order_header"=>[], "order_detail"=>[], "order_delivery"=>[]]; $sql = " select T_OrderHeaderID as order_id, T_OrderHeaderLabNumber as order_no, T_OrderHeaderDate as order_date, T_OrderHeaderSubTotal as order_subtotal, T_OrderHeaderRounding as order_rounding, T_OrderHeaderTotal as order_total, M_PatientName_enc, M_TitleName, M_PatientNoReg as patient_mr, M_MouName as order_mou, M_CompanyName as order_company, fn_global_doctor_name(da.M_DoctorID) doctor_sender, fn_global_doctor_name(db.M_DoctorID) doctor_pj, fn_global_doctor_address(aa.M_DoctorAddressID, 1) doctor_sender_address, M_MouIsBill M_CompanyIsBill, M_MouMinDP M_CompanyMinDP, M_MouIsAgingOnHold M_CompanyIsAgingOnHold, M_MouIsAgingOnHoldNote M_CompanyIsAgingOnHoldNote from t_orderheader join m_patient on T_OrderHeaderM_PatientID = M_PatientID join m_company on T_OrderHeaderM_CompanyID = M_CompanyID join m_mou on T_OrderHeaderM_MouID = M_MouID join m_doctor da on T_OrderHeaderSenderM_DoctorID = da.M_DoctorID join m_doctoraddress aa on T_OrderHeaderSenderM_DoctorAddressID = aa.M_DoctorAddressID join m_doctor db on T_OrderHeaderSenderM_DoctorID = db.M_DoctorID left join m_title on m_patientm_titleid = m_titleid where T_OrderHeaderID = ?"; $query = $this->db_smartone->query($sql, array($prm['id'])); if ($query) { $rows = (array) $query->row(); $name = $this->ibl_encryptor->decrypt($rows['M_PatientName_enc']); $title = !empty($rows['M_TitleName']) ? $rows['M_TitleName'] . ' ' : ''; $rows['patient_name'] = $title . ($name ?? ''); unset($rows['M_PatientName_enc'], $rows['M_TitleName']); $rst['order_header'] = $rows; // $result = array("status" => "OK" , "data" => $rst); // $this->sys_ok($result); // exit; } else { $this->sys_error_db("m_doctoraddress ", $this->db_smartone); exit; } $sql = "CALL sp_fo_payment_get_delivery('{$prm['id']}')"; $query = $this->db_smartone->query($sql); $this->clean_mysqli_connection($this->db_smartone->conn_id); if ($query) { $rows = $query->row(); $rst['order_delivery'] = json_decode($rows->delivery); // $result = array("status" => "OK" , "data" => $rst); // $this->sys_ok($result); // exit; } else { $this->sys_error_db("m_doctoraddress delivery ", $this->db_smartone); exit; } // { n:1, d_id:1, t_id:1, t_name:'SGOT', t_price:80000, t_disctotal:7000, t_total:73000 }, // { n:2, d_id:2, t_id:2, t_name:'SGPT', t_price:75000, t_disctotal:8000, t_total:67000 } // T_OrderDetailPrice double [0] // T_OrderDetailPriceForDisc double [0] // T_OrderDetailDisc double [0] // T_OrderDetailDiscAmount double [0] // T_OrderDetailTotal $sql = " select T_OrderDetailID as d_id, T_OrderDetailT_TestID as t_id, IFNULL(T_OrderDetailT_TestName, T_PacketName) as t_name, T_OrderDetailPrice as t_price, T_OrderDetailDiscTotal as t_disctotal, T_OrderDetailTotal as t_total from t_orderdetail join t_orderdetailaddon on T_OrderDetailAddOnT_OrderDetailID = T_OrderDetailID left join t_test on t_orderdetailt_testid = t_testid left join t_packet on t_orderdetailaddonispacket = 'Y' and t_orderdetailaddont_packetid = t_packetid where T_OrderDetailT_OrderHeaderID = ? and T_ORderDetailIsActive = 'Y' and ((T_ORderDetailAddOnIsPacket = 'N' AND T_TestIsPrintNota = 'Y' AND T_OrderDetailT_TestIsPanelChildren = 'N') OR (T_OrderDetailT_TestIsPanelChildren = 'Y' AND T_OrderDetailT_TestIsPanelChildrenPrintNota = 'Y') OR (T_ORderDetailAddOnIsPacket = 'Y' AND T_PacketIsNOta = 'Y'))"; $query = $this->db_smartone->query($sql, array($prm['id'])); if ($query) { $rows = $query->result_array(); $rst['order_detail'] = $rows; $result = array("status" => "OK" , "data" => $rst); $this->sys_ok($result); exit; } else { $this->sys_error_db("m_doctoraddress ", $this->db_smartone); exit; } } public function search() { $prm = $this->sys_input; $max_rst = 100; $tot_count =0; $q = [ 'search' => '%' ]; if ($prm['search'] != '') { $q['search'] = "%{$prm['search']}%"; } // QUERY TOTAL $sql = "select count(*) total from m_paymenttype where M_PaymentTypeIsActive = 'Y' and M_PaymentTypeName like ?"; $query = $this->db_smartone->query($sql, array($q['search'])); if ($query) { $tot_count = $query->result_array()[0]["total"]; } else { $this->sys_error_db("m_paymenttype count",$this->db_smartone); exit; } $sql = "select M_PaymentTypeID payment_type_id, M_PaymentTypeName payment_type_name, M_PaymentTypeCode payment_type_code, 0 payment_amount, '' payment_note, 'Nomor Kartu' payment_note_label, 'N' payment_enable, 0 payment_change, 0 payment_actual, 0 payment_card_id, 0 payment_edc_id, 0 payment_account_id from m_paymenttype where M_PaymentTypeIsActive = 'Y' and M_PaymentTypeName like ?"; $query = $this->db_smartone->query($sql, array($q['search'])); if ($query) { $rows = $query->result_array(); foreach($rows as $k => $v) { if ($v['payment_type_code'] == 'CASH') $v['payment_note_label'] = 'Kembali'; if ($v['payment_type_code'] == 'VOUCHER') $v['payment_note_label'] = 'Nomor Voucher'; $rows[$k] = $v; } $result = $rows; $this->sys_ok($result); } else { $this->sys_error_db("m_paymenttype rows",$this->db_smartone); exit; } } function save() { $prm = $this->sys_input; $payments_ibl = $prm['payments']; $klinik_payment_result = null; if (!empty($prm['order_klinik_id'])) { list($ok_order_klinik, $order_klinik_data) = $this->get_order_klinik_outstanding($prm['order_klinik_id']); if (!$ok_order_klinik) { $this->sys_error($order_klinik_data); exit; } $split = $this->split_payments_for_klinik($prm['payments'], $order_klinik_data['outstanding_total']); if ($split['allocated_total'] > 0) { list($ok_payment_klinik, $payment_klinik_data) = $this->save_payment_klinik( $prm['order_klinik_id'], $split['clinic_payments'], $this->sys_user['M_UserID'] ); if (!$ok_payment_klinik) { $this->sys_error_db($payment_klinik_data, $this->db_onedev); exit; } $klinik_payment_result = $payment_klinik_data; } $payments_ibl = $split['ibl_payments']; } $has_ibl_payment = false; foreach ($payments_ibl as $payment) { if (!empty($payment['chex']) && $this->payment_amount_net($payment) > 0) { $has_ibl_payment = true; break; } } if (!$has_ibl_payment) { $result = [ 'status' => 'OK', 'data' => [ 'status' => 'OK', 'order_klinik_payment' => $klinik_payment_result, 'ibl_payment' => null ] ]; $this->sys_ok($result['data']); exit; } $payment_json = json_encode($payments_ibl); $sql = "CALL sp_fo_payment('{$prm['order_id']}', '{$payment_json}', '{$this->sys_user['M_UserID']}');"; $query = $this->db_smartone->query($sql); if ($query) { $rst = $query->row(); $rst->data = json_decode($rst->data); if (is_object($rst->data)) { $rst->data->order_klinik_payment = $klinik_payment_result; } echo json_encode($rst); } else { $this->sys_error_db("save payment", $this->db_smartone); exit; } } function endshowtime() { $prm = $this->sys_input; $sql = "UPDATE t_orderheaderaddon SET T_OrderHeaderAddonFoTimeStart = '{$prm['time_start']}', T_OrderHeaderAddonFoTimeEnd = NOW() WHERE T_OrderHeaderAddOnT_OrderHeaderID = {$prm['order_id']}"; $query = $this->db_smartone->query($sql); if ($query) { $result = array( "total" => 1, "records" => array() ); $this->sys_ok($result); exit; } else { $this->sys_error_db("save payment", $this->db_smartone); exit; } } public function search_bank() { $prm = $this->sys_input; if (isset($prm['card'])) { $sql = "SELECT Nat_BankID, Nat_BankName FROM nat_bank WHERE Nat_BankIsCard = 'Y' ORDER BY Nat_BankName ASC"; $query = $this->db_smartone->query($sql); } else if (isset($prm['edc'])) { $sql = "SELECT Nat_BankID, Nat_BankName FROM nat_bank WHERE Nat_BankIsEDC = 'Y' ORDER BY Nat_BankName ASC"; $query = $this->db_smartone->query($sql); } else { $sql = "SELECT Nat_BankID, Nat_BankName FROM nat_bank ORDER BY Nat_BankName ASC"; $query = $this->db_smartone->query($sql); } if ($query) { $rows = $query->result_array(); $this->sys_ok(["records"=>$rows, "total"=>sizeof($rows), "q"=>$this->db_smartone->last_query()]); } else { $this->sys_error_db("NAT BANK",$this->db_smartone); exit; } } function generate_random_string() { $length = 32; $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $code = ''; for ($i = 0; $i < $length; $i++) { $code .= $characters[rand(0, strlen($characters) - 1)]; } return $code; } function save_signature() { if (! $this->isLogin) { $this->sys_error("Invalid Token"); exit; } $prm = $this->sys_input; $userid = $this->sys_user["M_UserID"]; $order_id = $prm['order_id']; $m_patientid = 0; $sql = "SELECT T_OrderHeaderM_PatientID FROM t_orderheader WHERE T_OrderHeaderID = ? LIMIT 1"; $query = $this->db_smartone->query($sql, array($order_id)); if ($query) { $rows = $query->row(); $m_patientid = $rows->T_OrderHeaderM_PatientID; } else { $this->sys_error_db("M_PatientID NOT FOUND", $this->db_smartone); exit; } $random_string = $this->generate_random_string(); $home_dir = "/home/one/project/one/"; $target_dir = $home_dir . "one-media/one-signature/" . date("Y") . "/"; if (!file_exists($target_dir)) { mkdir($target_dir, 0755, true); } $target_path = $target_dir . "_" . $random_string . ".png"; $sql = "UPDATE patient_signature SET Patient_SignatureIsActive = 'N', Patient_SignatureLastUpdated = NOW, Patient_SignatureLastUpdatedUserID = ? WHERE Patient_SignatureM_PatientID = ? AND Patient_SignatureIsActive = 'Y'"; $delete_exist = $this->db_onedev->query($sql, array($userid, $m_patientid)); /*if (file_exists($target_path)) { $random_string = $this->generate_random_string(); $new_path = $target_dir . "_" . $random_string . ".png"; $xsource = fopen($target_path, 'r'); $xdestination = fopen($new_path, 'w'); stream_copy_to_stream($xsource, $xdestination); fclose($xsource); fclose($xdestination); $new_path = "/" . str_replace($home_dir, "", $new_path); $sql = "UPDATE patient_signature SET Patient_SignatureIsActive = 'N', Patient_SignatureLastUpdated = NOW, Patient_SignatureLastUpdatedUserID = ? WHERE Patient_SignatureM_PatientID = ? AND Patient_SignatureIsActive = 'Y'"; $delete_exist = $this->db_onedev->query($sql, array($userid, $m_patientid)); $sql = "INSERT INTO patient_signature ( Patient_SignatureM_PatientID, Patient_SignatureUrl, Patient_SignatureCreated, Patient_SignatureUserID ) VALUES (?, ?, NOW(), ?)"; $insert_new = $this->db_onedev->query($sql, array($m_patientid, $new_path, $userid)); }*/ //echo $target_path; $file_png = $this->base64_to_jpeg($prm['data'], $target_path); $xurl = "/" . str_replace($home_dir, "", $target_path); if ($xurl) { $sql = "UPDATE patient_signature SET Patient_SignatureIsActive = 'N', Patient_SignatureLastUpdated = NOW(), Patient_SignatureLastUpdatedUserID = ? WHERE Patient_SignatureM_PatientID = ? AND Patient_SignatureIsActive = 'Y'"; $delete_exist = $this->db_onedev->query($sql, array($userid, $m_patientid)); //echo $this->db_onedev->last_query(); if(!$delete_exist) { echo $this->db_onedev->last_query(); $this->sys_error_db("DELETE PATIENT SIGNATURE", $this->db_onedev); exit; } $sql = "INSERT INTO patient_signature ( Patient_SignatureM_PatientID, Patient_SignatureUrl, Patient_SignatureCreated, Patient_SignatureCreatedUserID ) VALUES (?, ?, NOW(), ?)"; $insert_new = $this->db_onedev->query($sql, array($m_patientid, $xurl, $userid)); //echo $this->db_onedev->last_query(); if(!$insert_new) { echo $this->db_onedev->last_query(); $this->sys_error_db("INSERT PATIENT SIGNATURE", $this->db_onedev); exit; } } $xurl = $xurl . "?=" . date('Ymdhhis'); $result = array( "url_image" => $xurl ); $this->sys_ok($result); exit; } function base64_to_jpeg($base64_string, $output_file) { // open the output file for writing $ifp = fopen($output_file, 'wb'); // split the string on commas // $data[ 0 ] == "data:image/png;base64" // $data[ 1 ] == $data = explode(',', $base64_string); // we could add validation here with ensuring count( $data ) > 1 fwrite($ifp, base64_decode($data[1])); // clean up the file resource fclose($ifp); return $output_file; } function get_report_url_by_code() { if (! $this->isLogin) { $this->sys_error("Invalid Token"); exit; } $prm = $this->sys_input; $report_code = $prm['code_report']; $params = $prm['params']; $this->load->library("Reporturl"); $report_url = $this->reporturl->get_report_url_by_code($report_code, $params); if($report_url[0]){ $result = array( "url" => $report_url[1] ); $this->sys_ok($result); exit; } else{ $this->sys_error($report_url[1]); exit; } } /*function endshowtime() { $prm = $this->sys_input; $sql = "UPDATE t_orderheaderaddon SET T_OrderHeaderAddonFoTimeStart = {$prm['time_start']}, T_OrderHeaderAddonFoTimeEnd = NOW() WHERE T_OrderHeaderAddOnT_OrderHeaderID = {$prm['order_id']}"; $query = $this->db_smartone->query($sql); if ($query) { $rows = $query->result_array(); $this->sys_ok(["records"=>array(), "total"=>sizeof($rows), "q"=>''); } else { $this->sys_error_db("NAT BANK",$this->db_smartone); exit; } }*/ }