isLogin) { throw new Exception("Invalid token", 1); } $params = $this->sys_input; $keyword = "%"; if ($params['search'] != '') { $keyword .= $params['search'] . "%"; } $offset = 0; $limit = 5; if ($params['currentpage'] > 0) { $offset = ($params['currentpage'] - 1) * $limit; } // ── UNION base — invoice + downpayment + installment ─── $sql_base = " SELECT sp.SupplierPaymentID, sp.SupplierPaymentDate, sp.SupplierPaymentNumber, sp.SupplierPaymentAmount, sp.SupplierPaymentStatus, sp.SupplierPaymentIsVerif, sp.SupplierPaymentIsApproved, sp.SupplierPaymentIsActive, si.SupplierInvoiceID, si.SupplierInvoiceNumber, si.SupplierInvoiceDraftPaymentDate, sup.SupplierCode, sup.SupplierName, 'INVOICE' AS type FROM supplier_payment sp JOIN supplier_invoice si ON si.SupplierInvoiceID = sp.SupplierPaymentSupplierInvoiceID JOIN supplier sup ON sup.SupplierID = si.SupplierInvoiceSupplierID WHERE sp.SupplierPaymentSupplierInvoiceID > 0 UNION ALL SELECT sp.SupplierPaymentID, sp.SupplierPaymentDate, sp.SupplierPaymentNumber, sp.SupplierPaymentAmount, sp.SupplierPaymentStatus, sp.SupplierPaymentIsVerif, sp.SupplierPaymentIsApproved, sp.SupplierPaymentIsActive, dp.SupplierDownpaymentID * -1 AS SupplierInvoiceID, CONCAT('DP-', po.PurchaseOrderNumber) AS SupplierInvoiceNumber, dp.SupplierDownpaymentDueDate AS SupplierInvoiceDraftPaymentDate, dp_sup.SupplierCode AS SupplierCode, dp_sup.SupplierName AS SupplierName, 'DP' AS type FROM supplier_payment sp JOIN supplier_downpayment dp ON dp.SupplierDownpaymentID = sp.SupplierPaymentSupplierDownpaymentID JOIN supplier dp_sup ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID JOIN purchase_order po ON po.PurchaseOrderID = dp.SupplierDownpaymentPurchasOrderID WHERE sp.SupplierPaymentSupplierDownpaymentID IS NOT NULL UNION ALL SELECT sp.SupplierPaymentID, sp.SupplierPaymentDate, sp.SupplierPaymentNumber, sp.SupplierPaymentAmount, sp.SupplierPaymentStatus, sp.SupplierPaymentIsVerif, sp.SupplierPaymentIsApproved, sp.SupplierPaymentIsActive, 0 AS SupplierInvoiceID, CONCAT('INST-', si_inst.SupplierInvoiceNumber) AS SupplierInvoiceNumber, inst.SupplierInstallmentDueDate AS SupplierInvoiceDraftPaymentDate, inst_sup.SupplierCode AS SupplierCode, inst_sup.SupplierName AS SupplierName, 'INSTALLMENT' AS type FROM supplier_payment sp JOIN supplier_installment inst ON inst.SupplierInstallmentID = sp.SupplierPaymentSupplierInstallmentID JOIN supplier_invoice si_inst ON si_inst.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID JOIN supplier inst_sup ON inst_sup.SupplierID = inst.SupplierInstallmentSupplierID WHERE sp.SupplierPaymentSupplierInstallmentID IS NOT NULL"; // ── Outer: common filters + ordering + pagination ─────── $sql_data = " SELECT * FROM ($sql_base) AS combined WHERE SupplierPaymentIsActive = 'Y' AND SupplierPaymentNumber LIKE ? AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?)) AND (SupplierPaymentStatus = ? OR ? = 'All') ORDER BY SupplierPaymentID DESC LIMIT ? OFFSET ?"; $que_data = $this->db->query($sql_data, [ $keyword, $params['startdate'], $params['enddate'], $params['status'], $params['status'], $limit, $offset ]); if (!$que_data) { throw new Exception("[Error] failed get data supplier payment", 2); } // ── COUNT — wrap UNION in outer filter ────────────────── $sql_total = "SELECT COUNT(*) AS total FROM ($sql_base) AS combined WHERE SupplierPaymentIsActive = 'Y' AND SupplierPaymentNumber LIKE ? AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?)) AND (SupplierPaymentStatus = ? OR ? = 'All')"; $que_total = $this->db->query($sql_total, [ $keyword, $params['startdate'], $params['enddate'], $params['status'], $params['status'] ]); if (!$que_total) { throw new Exception("[Error] failed get total data supplier payment", 2); } $output = [ "records" => $que_data->result_array(), "total" => $que_total->row_array()['total'] ]; $this->sys_ok($output); } catch (Exception $exc) { $message = $exc->getMessage(); $code = $exc->getCode(); if ($code == 1) { $this->sys_error($message); } else { $this->sys_error_db($message); } exit; } } public function searchDetail() { try { if (!$this->isLogin) { throw new Exception("invalid token", 1); } $para = $this->sys_input; // ── Detect payment type ────────────────────────────────── $sql_type = "SELECT SupplierPaymentSupplierInvoiceID, SupplierPaymentSupplierDownpaymentID, SupplierPaymentSupplierInstallmentID FROM supplier_payment WHERE SupplierPaymentID = ? AND SupplierPaymentIsActive = 'Y'"; $que_type = $this->db->query($sql_type, [$para['paymentID']]); if (!$que_type) { throw new Exception("[Error] failed get payment header", 2); } $payment = $que_type->row_array(); if (!$payment) { throw new Exception("[Error] payment not found", 2); } // ── INVOICE branch ────────────────────────────────────── if ($payment['SupplierPaymentSupplierInvoiceID'] > 0) { $sql = "SELECT si.SupplierInvoiceSubTotal, si.SupplierInvoiceShippingCost, si.SupplierInvoiceDiscountPercent, si.SupplierInvoiceDiscountAmount, si.SupplierInvoiceTaxPercentPpn, si.SupplierInvoiceTaxAmountPpn, si.SupplierInvoiceGrandTotal, si.SupplierInvoiceID, 'INVOICE' AS type FROM supplier_payment sp JOIN supplier_invoice si ON si.SupplierInvoiceID = sp.SupplierPaymentSupplierInvoiceID WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'"; $que = $this->db->query($sql, [$para['paymentID']]); if (!$que) { throw new Exception("[Error] failed get row data", 2); } $data = $que->row_array(); $sql_detail = "SELECT M_ItemDesc, SupplierInvoiceDetailQty, SupplierInvoiceDetailPrice, SupplierInvoiceDetailDiscountAmount, (SupplierInvoiceDetailPrice - SupplierInvoiceDetailDiscountAmount) AS DiscountedPrice, SupplierInvoiceDetailTotal FROM supplier_payment_detail JOIN supplier_invoice_detail ON SupplierInvoiceDetailIsActive = 'Y' AND SupplierPaymentDetailSupplierPaymentID = ? AND SupplierInvoiceDetailSupplierInvoiceID = ? JOIN m_item ON M_ItemID = SupplierInvoiceDetailItemID AND M_ItemIsActive = 'Y' GROUP BY SupplierInvoiceDetailID"; $que_detail = $this->db->query($sql_detail, [ $para['paymentID'], $data['SupplierInvoiceID'] ]); if (!$que_detail) { throw new Exception("[Error] failed to get item payments", 2); } unset($data['SupplierInvoiceID']); $data['detail'] = $que_detail->result_array(); // ── DOWNPAYMENT branch ────────────────────────────────── } elseif ($payment['SupplierPaymentSupplierDownpaymentID'] > 0) { $sql = "SELECT dp.SupplierDownpaymentPurchasOrderID, dp.SupplierDownpaymentAmount AS SupplierInvoiceSubTotal, 0 AS SupplierInvoiceShippingCost, 0 AS SupplierInvoiceDiscountPercent, 0 AS SupplierInvoiceDiscountAmount, 0 AS SupplierInvoiceTaxPercentPpn, 0 AS SupplierInvoiceTaxAmountPpn, dp.SupplierDownpaymentAmount AS SupplierInvoiceGrandTotal, 'DP' AS type FROM supplier_payment sp JOIN supplier_downpayment dp ON dp.SupplierDownpaymentID = sp.SupplierPaymentSupplierDownpaymentID WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'"; $que = $this->db->query($sql, [$para['paymentID']]); if (!$que) { throw new Exception("[Error] failed get DP row data", 2); } $data = $que->row_array(); $sql_detail = "SELECT CONCAT('DP-', M_ItemDesc) AS M_ItemDesc, PurchaseOrderDetailQty AS SupplierInvoiceDetailQty, PurchaseOrderDetailPrice AS SupplierInvoiceDetailPrice, PurchaseOrderSummaryDiscountAmount AS SupplierInvoiceDetailDiscountAmount, (PurchaseOrderDetailPrice - PurchaseOrderSummaryDiscountAmount) AS DiscountedPrice, PurchaseOrderSummaryTotal AS SupplierInvoiceDetailTotal FROM supplier_downpayment JOIN purchase_order ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID JOIN purchase_order_detail ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID AND PurchaseOrderDetailIsActive = 'Y' JOIN purchase_order_summary ON PurchaseOrderSummaryID = PurchaseOrderDetailPurchaseSummaryID AND PurchaseOrderSummaryIsActive = 'Y' JOIN m_item ON M_ItemID = PurchaseOrderDetailItemID WHERE SupplierDownpaymentPurchasOrderID = ?"; $que_detail = $this->db->query($sql_detail, [ $data['SupplierDownpaymentPurchasOrderID'] ]); if (!$que_detail) { throw new Exception('failed to get dp detail', 2); } $data['detail'] = $que_detail->result_array(); } else { $sql = "SELECT inst.SupplierInstallmentAmount AS SupplierInvoiceSubTotal, 0 AS SupplierInvoiceShippingCost, 0 AS SupplierInvoiceDiscountPercent, 0 AS SupplierInvoiceDiscountAmount, 0 AS SupplierInvoiceTaxPercentPpn, 0 AS SupplierInvoiceTaxAmountPpn, inst.SupplierInstallmentAmount AS SupplierInvoiceGrandTotal, si.SupplierInvoiceID, 'INSTALLMENT' AS type FROM supplier_payment sp JOIN supplier_installment inst ON inst.SupplierInstallmentID = sp.SupplierPaymentSupplierInstallmentID JOIN supplier_invoice si ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'"; $que = $this->db->query($sql, [$para['paymentID']]); if (!$que) { throw new Exception("[Error] failed get Installment row data", 2); } $data = $que->row_array(); $sql_detail = "SELECT M_ItemDesc, SupplierInvoiceDetailQty, SupplierInvoiceDetailPrice, SupplierInvoiceDetailDiscountAmount, (SupplierInvoiceDetailPrice - SupplierInvoiceDetailDiscountAmount) AS DiscountedPrice, SupplierInvoiceDetailTotal FROM supplier_invoice_detail JOIN m_item ON M_ItemID = SupplierInvoiceDetailItemID AND M_ItemIsActive = 'Y' WHERE SupplierInvoiceDetailSupplierInvoiceID = ? AND SupplierInvoiceDetailIsActive = 'Y' GROUP BY SupplierInvoiceDetailID"; $que_detail = $this->db->query($sql_detail, [$data['SupplierInvoiceID']]); if (!$que_detail) { throw new Exception("[Error] failed to get installment item payments", 2); } unset($data['SupplierInvoiceID']); $data['detail'] = $que_detail->result_array(); } $this->sys_ok($data); } catch (Exception $exc) { $message = $exc->getMessage(); $code = $exc->getCode(); if ($code == 1) { $this->sys_error($message); } else { $this->sys_error_db($message); } exit; } } public function getUserApproveLevel() { try { if (!$this->isLogin) { throw new Exception("Invalid token", 1); } $userid = $this->sys_user['M_UserID']; $sql_level = "SELECT M_UserM_ApproveLevelID AS level FROM m_user WHERE M_UserIsActive = 'Y' AND M_UserID = ? "; $que_level = $this->db->query($sql_level, [$userid]); if (!$que_level) { throw new Exception("[Error] failed get user approve level", 2); } $data = $que_level->row_array(); $this->sys_ok($data); } catch (Exception $exc) { $message = $exc->getMessage(); $code = $exc->getCode(); if ($code == 1) { $this->sys_error($message); } else { $this->sys_error_db($message); } exit; } } public function updateStatusPayment() { try { if (!$this->isLogin) { throw new Exception("Invalid token", 1); } $this->db->trans_begin(); $para = $this->sys_input; $user = $this->sys_user; if ($para['userlevel'] == '1') { $sql = "UPDATE supplier_payment SET SupplierPaymentIsVerif = 'Y', SupplierPaymentStatus = 'Verified', SupplierPaymentVerifUserID = ?, SupplierPaymentVerifDate = NOW() WHERE SupplierPaymentID = ? AND SupplierPaymentIsActive = 'Y'"; $query = $this->db->query($sql, [ $user['M_UserID'], $para['paymentID'] ]); if (!$query) { $this->db->trans_rollback(); throw new Exception("[Error] failed update status verified", 2); } } if ($para['userlevel'] == '2') { $sql = "UPDATE supplier_payment SET SupplierPaymentIsApproved = 'Y', SupplierPaymentStatus = 'Approved', SupplierPaymentApprovedUserID = ?, SupplierPaymentApprovedDate = NOW() WHERE SupplierPaymentID = ? AND SupplierPaymentIsActive = 'Y'"; $query = $this->db->query($sql, [ $user['M_UserID'], $para['paymentID'] ]); if (!$query) { $this->db->trans_rollback(); throw new Exception("[Error] failed update status approved", 2); } } $this->db->trans_commit(); $this->sys_ok("[Success] success update status Payment"); } catch (Exception $exc) { $message = $exc->getMessage(); $code = $exc->getCode(); if ($code == 1) { $this->sys_error($message); } else { $this->sys_error_db($message); } exit; } } }