FHM09062601IBL - split klinik payment before ibl

This commit is contained in:
sas.fajri
2026-06-12 15:15:47 +07:00
parent 9eb92eb340
commit 567f85a0b9

View File

@@ -12,9 +12,219 @@ 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