diff --git a/application/controllers/mockup/fo/ibl_registration/Payment.php b/application/controllers/mockup/fo/ibl_registration/Payment.php index 6310cbfc..73d57470 100644 --- a/application/controllers/mockup/fo/ibl_registration/Payment.php +++ b/application/controllers/mockup/fo/ibl_registration/Payment.php @@ -12,8 +12,218 @@ class Payment extends MY_Controller { parent::__construct(); $this->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; @@ -180,8 +390,54 @@ class Payment extends MY_Controller function save() { $prm = $this->sys_input; - $payment_json = json_encode($prm['payments']); + $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); @@ -189,6 +445,9 @@ class Payment extends MY_Controller { $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