From e1feaa68a883d36afa9b49c2129eb63a3241b6db Mon Sep 17 00:00:00 2001 From: sasadib Date: Tue, 21 Jul 2026 15:21:24 +0700 Subject: [PATCH] feature: payment instruction & cashier case cicilan dan downpayment --- .../receive-item-po/ReceiveItemPOAsset.php | 231 ++++- .../ReceiveItemPoInventaris.php | 74 +- .../scheduler/PurchaseInvoiceInstallment.http | 122 +-- .../scheduler/PurchaseInvoiceInstallment.php | 701 ++++---------- .../supplierpaymentapprovedv3/Billv2.php | 84 +- .../mockup/supplierpaymentcashierv5/Bill.php | 202 +++- .../supplierpaymentcashierv5/PaymentV2.php | 758 ++++++++------- .../mockup/supplierpaymentv4/Bill.php | 275 +++++- .../mockup/supplierpaymentv4/Payment.php | 871 +++++++++++------- 9 files changed, 1930 insertions(+), 1388 deletions(-) diff --git a/application/controllers/mockup/receive-item-po/ReceiveItemPOAsset.php b/application/controllers/mockup/receive-item-po/ReceiveItemPOAsset.php index 4affc1e..d07233a 100644 --- a/application/controllers/mockup/receive-item-po/ReceiveItemPOAsset.php +++ b/application/controllers/mockup/receive-item-po/ReceiveItemPOAsset.php @@ -1127,11 +1127,14 @@ class ReceiveItemPOAsset extends MY_Controller PurchaseOrderSummaryQty as QtyAllPO, PurchaseOrderSummaryTotal as TotalAllPO, PurchaseOrderDiscountPercent AS DiscPOPercent, - PurchaseOrderDiscountAmount AS DiscPORupiah + PurchaseOrderDiscountAmount AS DiscPORupiah, + M_ItemItem_CategoryID FROM receive_order_po_detail JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID JOIN purchase_order_summary ON ReceiveOrderPoDetailPurchaseOrderSummaryID = PurchaseOrderSummaryID AND PurchaseOrderSummaryIsActive = 'Y' + JOIN m_item ON M_ItemID = ReceiveOrderPoItemID + AND M_ItemIsActive = 'Y' WHERE ReceiveOrderPoDetailReceiveOrderPoID = ? AND ReceiveOrderPoDetailIsActive='Y' GROUP BY ReceiveOrderPoDetailID"; @@ -1268,13 +1271,13 @@ class ReceiveItemPOAsset extends MY_Controller /* INSERT table jurnal tx item */ $sql_jurnaltx = "INSERT INTO jurnal_tx ( - jurnalTxJurnalID, - jurnalTxCoaID, - jurnalTxDescription, - jurnalTxDebit, - jurnalTxCredit, - jurnalTxM_UserID - ) VALUES (?,?,?,?,?,?)"; + jurnalTxJurnalID, + jurnalTxCoaID, + jurnalTxDescription, + jurnalTxDebit, + jurnalTxCredit, + jurnalTxM_UserID + ) VALUES (?,?,?,?,?,?)"; $que_jurnaltx = $this->db->query($sql_jurnaltx, [ $jurnalID, $coa_asset['Fa_ClassCoaID'], @@ -1291,14 +1294,14 @@ class ReceiveItemPOAsset extends MY_Controller /* INSERT table jurnal addon item */ $sql_jurnaladdon = "INSERT INTO jurnal_addon ( - jurnalAddOnJurnalID, - jurnalAddOnJurnalTxID, - jurnalAddOnCode, - jurnalAddOnValue, - jurnalAddOnM_ItemID, - jurnalAddOnCreated, - jurnalAddOnCreatedUserID - ) VALUES (?,?,'PONUMB',?,?,NOW(),?)"; + jurnalAddOnJurnalID, + jurnalAddOnJurnalTxID, + jurnalAddOnCode, + jurnalAddOnValue, + jurnalAddOnM_ItemID, + jurnalAddOnCreated, + jurnalAddOnCreatedUserID + ) VALUES (?,?,'PONUMB',?,?,NOW(),?)"; $que_jurnaladdon = $this->db->query($sql_jurnaladdon, [ $jurnalID, $jurnalTXID, @@ -1354,7 +1357,7 @@ class ReceiveItemPOAsset extends MY_Controller throw new Exception("[Error] failed get account diskon", 1); } $coa_diskon = $que_coadiskon->row_array(); - foreach ($input_diskon as $key => $val) { + foreach ($input_diskon as $idx => $val) { if (doubleval($val) <= 0.00) { continue; } @@ -1397,10 +1400,199 @@ class ReceiveItemPOAsset extends MY_Controller $this->db->trans_rollback(); throw new Exception("[Error] save diskon prorate", 1); } + + + /* handling table stock */ + $sql_cekstock = "SELECT * + FROM stock s + JOIN m_item i ON s.StockItemID = i.M_ItemID + WHERE s.StockItemID = ? + AND s.StockItemUnitID = ? + AND s.StockWarehouseID = ? + AND i.M_ItemItem_CategoryID = ?"; + $que_cekstock = $this->db->query($sql_cekstock, [ + $elem['ReceiveOrderPoItemID'], + $elem['ReceiveOrderPoItemUnitID'], + $data_ro['ReceiveOrderPoWarehouseID'], + $elem['M_ItemItem_CategoryID'] + ]); + if (!$que_cekstock) { + $this->db->trans_rollback(); + throw new Exception("[Error] failed to check item exist in stock", 1); + } + + $stock_exist = $que_cekstock->row_array(); + $stock_ID = $stock_exist['StockID']; + $stock_qty_ori = intval($stock_exist['StockQty']); + $stock_price = doubleval($stock_exist['StockItemPrice']); + $stock_qty_end = 0; + + if (!empty($stock_exist)) { + $stock_qty_end = $stock_qty_ori + intval($elem['ReceiveOrderPoDetailQty']); + $all_price = ($stock_qty_ori * $stock_price) + (intval($elem['ReceiveOrderPoDetailQty']) * doubleval($elem['ReceiveOrderPoDetailPrice'])); + $avg_price = round($all_price / $stock_qty_end, 2); + + $sql_update_stock = "UPDATE stock SET + StockItemPrice = ?, + StockQty = ?, + StockLastUpdated = NOW(), + StockUserID = ? + WHERE StockID = ?"; + $que_update_stock = $this->db->query($sql_update_stock, [ + $avg_price, + $stock_qty_end, + $user['M_UserID'], + $stock_ID + ]); + if (!$que_update_stock) { + $this->db->trans_rollback(); + throw new Exception("[Error] failed to update stock", 1); + } + } else { + $sql_insert_stock = "INSERT INTO stock ( + StockWarehouseAlmariID, + StockWarehouseRackID, + StockWarehouseID, + StockStockNumber, + StockItemID, + StockItemUnitID, + StockItemPrice, + StockQty, + StockLastUpdated, + StockUserID + ) VALUES (0,0,?,fn_numbering('SN'),?,?,?,?,NOW(),?)"; + $que_insert_stock = $this->db->query($sql_insert_stock, [ + $data_ro['ReceiveOrderPoWarehouseID'], + $elem['ReceiveOrderPoItemID'], + $elem['ReceiveOrderPoItemUnitID'], + $elem['ReceiveOrderPoDetailPrice'], + $elem['ReceiveOrderPoDetailQty'], + $user['M_UserID'] + ]); + if (!$que_insert_stock) { + $this->db->trans_rollback(); + throw new Exception("[Error] failed to insert stock", 1); + } + + $stock_ID = $this->db->insert_id(); + $stock_qty_ori = 0; + $stock_qty_end = intval($elem['ReceiveOrderPoDetailQty']); + } + + /* insert stock card */ + $sql_stock_card = "INSERT INTO stockcard ( + StockCardWarehouseID, + StockCardDatetime, + StockCardItemID, + StockCardItemUnitID, + StockCardReffID, + StockCardStatus, + StockCardBefore, + StockCardIn, + StockCardOut, + StockCardAfter, + StockCardUserID + ) VALUES (?, NOW(), ?, ?, ?, 'PRV', ?, ?, 0, ?, ?)"; + $que_stock_card = $this->db->query($sql_stock_card, [ + $data_ro['ReceiveOrderPoWarehouseID'], + $elem['ReceiveOrderPoItemID'], + $elem['ReceiveOrderPoItemUnitID'], + $stock_ID, + $stock_qty_ori, + $elem['ReceiveOrderPoDetailQty'], + $stock_qty_end, + $user['M_UserID'] + ]); + if (!$que_stock_card) { + $this->db->trans_rollback(); + throw new Exception("[Error] failed to insert stock card", 1); + } + + /* insert stock log */ + $sql_stock = "SELECT * FROM stock WHERE StockID = ?"; + $que_stock = $this->db->query($sql_stock, [$stock_ID]); + if (!$que_stock) { + $this->db->trans_rollback(); + throw new Exception("[Error] failed to cek latest stock", 1); + } + $stock_latest = $que_stock->row_array(); + + $sql_stock_log = "INSERT INTO stocklog ( + StockLogWarehouseID, + StockLogDateTime, + StockLogItemID, + StockLogItemUnitID, + StockLogStockNumber, + StockLogReffID, + StockLogStatus, + StockLogQty, + StockLogUserID + ) VALUES (?, NOW(), ?, ?, ?, ?, 'PRV', ?, ?)"; + $que_stock_log = $this->db->query($sql_stock_log, [ + $data_ro['WarehouseID'], + $elem['ReceiveOrderPoItemID'], + $elem['ReceiveOrderPoItemUnitID'], + $stock_latest['StockStockNumber'], + $stock_ID, + $elem['ReceiveOrderPoDetailQty'], + $user['M_UserID'] + ]); + if (!$que_stock_log) { + $this->db->trans_rollback(); + throw new Exception("[Error] failed insert stock log", 1); + } + } + + /* handle shipping */ + $ship_cost = round(doubleval($data_ro['ReceiveOrderShippingCostAmount']), 2); + if ($ship_cost > 0.00) { + $sql_tx_ship = "INSERT INTO jurnal_tx ( + jurnalTxJurnalID, + jurnalTxCoaID, + jurnalTxDescription, + jurnalTxDebit, + jurnalTxCredit, + jurnalTxM_UserID + ) SELECT ?, coaID, coaDescription, ?, 0, ? + FROM coa WHERE coaAccountNo = '5320700001' LIMIT 1"; + $que_tx_ship = $this->db->query($sql_tx_ship, [$jurnalID, $ship_cost, $user['M_UserID']]); + if (!$que_tx_ship) { + $this->db->trans_rollback(); + throw new Exception("[Error] failed insert jurnal shipping", 1); + } + + $sql_rec_ship = "INSERT INTO receive_order_po_shipping ( + ReceiveOrderPoShippingPurchaseOrderID, + ReceiveOrderPoShippingReceiveOrderPoID, + ReceiveOrderPoShippingAmount, + ReceiveOrderPoShippingStatus, + ReceiveOrderPoShippingIsActive, + ReceiveOrderPoShippingCreatedUserID + ) SELECT + PurchaseOrderID, + {$roID}, + PurchaseOrderShippingCost, + PurchaseOrderShippingCostStatus, + 'Y', + {$user['M_UserID']} + FROM purchase_order + WHERE PurchaseOrderID IN ( + SELECT DISTINCT ReceiveOrderPoDetailPurchaseOrderID + FROM receive_order_po + JOIN receive_order_po_detail ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID + WHERE ReceiveOrderPoID = {$user['M_UserID']} + ) + AND PurchaseOrderShippingCost IS NOT NULL + AND PurchaseOrderShippingCost > 0"; + $que_rec_ship = $this->db->query($sql_rec_ship, []); + if (!$que_rec_ship) { + $this->db->trans_rollback(); + throw new Exception("[Error] failed insert table shipping", 1); + } } # INSERT jurnal tx for GRNI # - $total_grni = round($total_debet - ($total_diskonitem + $total_diskonpo), 2); + $total_grni = round($total_debet - ($total_diskonitem + $total_diskonpo), 2) + $ship_cost; $sql_grni = "INSERT INTO jurnal_tx ( jurnalTxJurnalID, jurnalTxCoaID, @@ -1533,10 +1725,11 @@ class ReceiveItemPOAsset extends MY_Controller SupplierInvoiceGrandTotal, SupplierInvoiceUnpaid, SupplierInvoiceNote, + SupplierInvoiceIsInstallment, SupplierInvoiceReceiveDate, SupplierInvoiceReceivedBy, SupplierInvoiceCreatedUserID - ) VALUES (?,?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?,NOW(),?,?)"; + ) VALUES (?,?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?,'Y',NOW(),?,?)"; $que_insert_pi = $this->db->query($sql_insert_pi, [ $num_pi, $data_ro['ReceiveOrderPoID'], diff --git a/application/controllers/mockup/receive-item-po/ReceiveItemPoInventaris.php b/application/controllers/mockup/receive-item-po/ReceiveItemPoInventaris.php index f83678a..18df7ba 100644 --- a/application/controllers/mockup/receive-item-po/ReceiveItemPoInventaris.php +++ b/application/controllers/mockup/receive-item-po/ReceiveItemPoInventaris.php @@ -1705,22 +1705,38 @@ class ReceiveItemPoInventaris extends MY_Controller exit; } - $sql_coa_inv = "SELECT - CoaMapInventarisCoaID, - CoaMapInventarisCoaNo, - CoaMapInventarisCoaDesc - FROM coa_map_inventaris - WHERE CoaMapInventarisM_InventarisGolID = ? - AND CoaMapInventarisIsActive = 'Y'"; - $que_coa_inv = $this->db->query($sql_coa_inv, [$item_cek['M_ItemM_InventarisGolID']]); - if (!$que_coa_inv) { + $sql_invcoa = "SELECT + COALESCE( + i.M_InventarisItemCoaMappingID, + g.M_InventarisCoaMappingID + ) AS MappingID, + COALESCE( + i.M_InventarisItemCoaMappingCoaInventarisID, + g.M_InventarisCoaMappingCoaInventarisID + ) AS CoaInventarisID, + c.coaDescription AS CoaInventarisDesc + FROM (SELECT 1) AS inventory + LEFT JOIN m_inventaris_item_coa_mapping i + ON i.M_InventarisItemCoaMappingM_ItemID = ? + AND i.M_InventarisItemCoaMappingIsActive = 'Y' + LEFT JOIN m_inventaris_coa_mapping g + ON g.M_InventarisCoaMappingM_InventarisGolID = ? + AND g.M_InventarisCoaMappingIsActive = 'Y' + LEFT JOIN coa c + ON c.coaID = COALESCE(i.M_InventarisItemCoaMappingCoaInventarisID, g.M_InventarisCoaMappingCoaInventarisID) + AND c.coaIsActive = 'Y'"; + $que_invcoa = $this->db->query($sql_invcoa, [ + $item_cek['M_ItemID'], + $item_cek['M_ItemM_InventarisGolID'] + ]); + if (!$que_invcoa) { $this->db->trans_rollback(); $this->sys_error_db("[Error] failed to get coa biaya item inventaris"); exit; } - $iteminv_coa = $que_coa_inv->row_array(); + $iteminv_coa = $que_invcoa->row_array(); - if (empty($iteminv_coa['CoaMapInventarisCoaID'])) { + if (empty($iteminv_coa['CoaInventarisID'])) { $this->db->trans_rollback(); $this->sys_error_db("[Error] coa gol inventaris not found"); exit; @@ -1740,8 +1756,8 @@ class ReceiveItemPoInventaris extends MY_Controller ) VALUES (?,?,?,?,?,?)"; $que_tx_jurnal = $this->db->query($sql_tx_jurnal, [ $jurnal_ID, - $iteminv_coa['CoaMapInventarisCoaID'], - $iteminv_coa['CoaMapInventarisCoaDesc'], + $iteminv_coa['CoaInventarisID'], + $iteminv_coa['CoaInventarisDesc'], $debet, 0, $user['M_UserID'] @@ -1754,7 +1770,7 @@ class ReceiveItemPoInventaris extends MY_Controller } $juranl_tx_ID = $this->db->insert_id(); $each_desc[] = "- Add detail Jurnal debet {$item_cek['M_ItemDesc']} - {$iteminv_coa['CoaMapInventarisCoaDesc']} sejumlah {$this->formatRupiah($debet)}"; + {$iteminv_coa['CoaInventarisDesc']} sejumlah {$this->formatRupiah($debet)}"; # INSERT JURNAL ADDON # $sql_addon_jurnal = "INSERT INTO jurnal_addon ( @@ -1944,20 +1960,6 @@ class ReceiveItemPoInventaris extends MY_Controller $this->sys_error_db("[Error] insert update stock"); exit; } - - // insert stockid barcode barang - // $sql_update_barcode = "UPDATE t_barcode_barang SET - // T_BarcodeBarangStockID = ? - // WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?"; - // $qry_update_barcode = $this->db->query($sql_update_barcode, [ - // $stock_ID, - // $detail['ReceiveOrderPoDetailID'] - // ]); - // if (!$qry_update_barcode) { - // $this->db->trans_rollback(); - // $this->sys_error_db("[Error] update barcode stockID", $this->db); - // exit; - // } } else { $sql_insert_stock = "INSERT INTO stock ( StockWarehouseAlmariID, @@ -1985,23 +1987,9 @@ class ReceiveItemPoInventaris extends MY_Controller exit; } - $stockID = $this->db->insert_id(); + $stock_ID = $this->db->insert_id(); $stock_qty_ori = 0; $stock_qty_end = intval($batch['qty']); - - // insert stockid barcode barang - // $sql_update_barcode = "UPDATE t_barcode_barang SET - // T_BarcodeBarangStockID = ? - // WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?"; - // $qry_update_barcode = $this->db->query($sql_update_barcode, [ - // $stockID, - // $detail['ReceiveOrderPoDetailID'] - // ]); - // if (!$qry_update_barcode) { - // $this->db->trans_rollback(); - // $this->sys_error_db("[Error] update barcode stockID", $this->db); - // exit; - // } } // insert stock card diff --git a/application/controllers/mockup/scheduler/PurchaseInvoiceInstallment.http b/application/controllers/mockup/scheduler/PurchaseInvoiceInstallment.http index 8b732df..59121cf 100644 --- a/application/controllers/mockup/scheduler/PurchaseInvoiceInstallment.http +++ b/application/controllers/mockup/scheduler/PurchaseInvoiceInstallment.http @@ -1,78 +1,55 @@ # ============================================================ # FILE : PurchaseInvoiceInstallment.http -# MODUL : Scheduler — Generate Purchase Invoice Cicilan Aset +# MODUL : Scheduler — Generate Supplier Installment Cicilan Aset # ============================================================ # # DESKRIPSI # --------- -# File ini berisi kumpulan HTTP request untuk menguji endpoint -# scheduler yang secara otomatis membuat Purchase Invoice (PI) -# cicilan bulanan berdasarkan kontrak aset aktif. +# File ini berisi HTTP request untuk menguji endpoint scheduler +# yang secara otomatis membuat baris cicilan ke tabel +# supplier_installment setiap bulan. # # CARA PAKAI # ---------- # 1. Gunakan ekstensi "REST Client" di VS Code (humao.rest-client) # atau tool sejenis (IntelliJ HTTP Client, Postman, dll). -# 2. Ganti nilai @host sesuai environment (local / staging / prod). -# 3. Klik "Send Request" di atas tiap blok ### untuk menjalankan -# request tersebut secara individual. -# 4. Jalankan request secara BERURUTAN sesuai urutan yang disarankan -# (lihat keterangan tiap endpoint di bawah). +# 2. Ganti nilai @host sesuai environment. +# 3. Klik "Send Request" di atas tiap blok ### # -# ALUR PENGGUNAAN YANG DISARANKAN -# -------------------------------- -# [1] ListEligibleContracts → Lihat kontrak mana saja yang akan diproses -# [2] GenerateMonthlyInvoices → Jalankan proses generate PI cicilan sekaligus -# [3] InsertSupplierInvoice → (Opsional) Insert manual 1 PI jika diperlukan +# ALUR +# ---- +# [1] GenerateMonthlyInvoices → Jalankan proses generate installment # # CATATAN # ------- -# - startDate & endDate menentukan periode bulan yang diproses. -# Biasanya diisi dengan tanggal awal dan akhir bulan berjalan. -# - Scheduler ini AMAN dijalankan ulang (idempotent). Kontrak yang -# sudah punya PI di bulan yang sama akan dilewati otomatis. -# - userID pada InsertSupplierInvoice akan diabaikan; sistem -# mengambil userID dari PurchaseOrderAssetContractCreatedUserID. +# - Default periode: bulan berjalan (tanggal 1 s/d akhir bulan) +# - Aman dijalankan ulang — dedup berdasarkan PO + bulan mencegah +# duplikasi +# - Tidak membuat jurnal — jurnal dibuat saat pembayaran cashier +# - Tidak update kontrak — InstallmentPaid diupdate saat pembayaran # ============================================================ @host = https://accone.aplikasi.web.id/one-api # ============================================================ -# [1] LIST KONTRAK ELIGIBLE +# [1] GENERATE INSTALLMENT BULANAN (MAIN ENDPOINT) # ============================================================ -# Gunakan endpoint ini SEBELUM generate untuk melihat preview -# kontrak mana saja yang akan dibuatkan PI pada periode ini. +# Satu request ini akan: +# Step 1: Validasi kontrak (aktif, belum lunas, dalam rentang) +# Step 2: Validasi PO (Approved, Active) +# Step 3: Validasi RO (Confirmed, Active) +# Step 4: Validasi parent invoice (IsInstallment = 'Y') +# Step 5: Cek dedup (belum ada installment bulan ini) +# Step 6: INSERT ke supplier_installment (Status = 'Pending') # -# Response berisi daftar kontrak beserta detail cicilan, -# status GRNI, dan apakah PI bulan ini sudah ada atau belum. +# Response: +# - totalEligible : jumlah kontrak lolos validasi +# - totalInserted : jumlah baris berhasil diinsert +# - created[] : detail tiap installment yang dibuat # ============================================================ -### [1] List kontrak cicilan eligible yang belum diproses bulan ini -POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/ListEligibleContracts -Content-Type: application/json - -{ - "startDate": "2026-07-01", - "endDate": "2026-07-31" -} - -# ============================================================ -# [2] GENERATE PI CICILAN BULANAN (MAIN ENDPOINT) -# ============================================================ -# Endpoint utama scheduler. Satu request ini akan: -# 1. Mengambil semua kontrak aset aktif yang eligible. -# 2. Mengecek duplikasi — melewati kontrak yang sudah ada PI-nya. -# 3. Membuat nomor PI via fn_penomoran() berdasarkan user -# pembuat kontrak (PurchaseOrderAssetContractCreatedUserID). -# 4. Insert supplier_invoice + supplier_invoice_detail. -# -# Response berisi: -# - berhasil : daftar PI yang berhasil dibuat (dengan nomorPI, supplierInvoiceID, dll) -# - dilewati : daftar kontrak yang dilewati beserta alasannya -# ============================================================ - -### [2] Generate PI cicilan untuk semua kontrak pada periode ini +### [1] Generate installment untuk periode tertentu POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices Content-Type: application/json @@ -81,47 +58,8 @@ Content-Type: application/json "endDate": "2026-07-31" } -# ============================================================ -# [3] INSERT MANUAL SATU PI (INTERNAL / DEBUG) -# ============================================================ -# Endpoint ini dipanggil INTERNAL oleh GenerateMonthlyInvoices -# via cURL. Gunakan hanya untuk debugging atau insert manual -# satu PI tertentu tanpa menjalankan proses batch. -# -# FIELD WAJIB: -# - nomorPI : Nomor PI (format dari fn_penomoran) -# - tanggalPI : Tanggal invoice (YYYY-MM-DD) -# - tanggalJatuhTempo : Tanggal jatuh tempo (YYYY-MM-DD) -# - jumlahCicilan : Nominal cicilan (angka, dalam Rupiah) -# - catatan : Catatan singkat pada header invoice -# - deskripsi : Deskripsi baris detail invoice -# - userID : ID user pembuat (ambil dari kontrak) -# - purchaseOrderAssetContractID : ID kontrak aset -# - purchaseOrderID : ID Purchase Order -# - receiveOrderPoID : ID Receive Order PO (GRNI) -# - supplierID : ID Supplier -# - purchaseOrderSummaryID : ID summary item PO -# - purchaseOrderSummaryItemID : ID item (barang/aset) -# - purchaseOrderSummaryItemUnitID: ID satuan item -# ============================================================ - -### [3] Insert satu supplier_invoice cicilan secara manual (debug) -POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallmentInsert/InsertSupplierInvoice +### [1a] Generate installment bulan berjalan (tanpa parameter) +POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices Content-Type: application/json -{ - "nomorPI": "PI-2026-07-0001", - "tanggalPI": "2026-07-31", - "tanggalJatuhTempo": "2026-08-14", - "jumlahCicilan": 15000000, - "catatan": "PI Cicilan Otomatis — Kontrak Aset ID 123 periode 2026-07", - "deskripsi": "Cicilan Kontrak Aset — Kendaraan Operasional periode 2026-07", - "userID": 1, - "purchaseOrderAssetContractID": 123, - "purchaseOrderID": 456, - "receiveOrderPoID": 789, - "supplierID": 12, - "purchaseOrderSummaryID": 111, - "purchaseOrderSummaryItemID": 222, - "purchaseOrderSummaryItemUnitID": 333 -} +{} diff --git a/application/controllers/mockup/scheduler/PurchaseInvoiceInstallment.php b/application/controllers/mockup/scheduler/PurchaseInvoiceInstallment.php index 2131efb..4718884 100644 --- a/application/controllers/mockup/scheduler/PurchaseInvoiceInstallment.php +++ b/application/controllers/mockup/scheduler/PurchaseInvoiceInstallment.php @@ -3,20 +3,19 @@ /** * PurchaseInvoiceInstallment * - * Digunakan oleh CRON untuk membuat Purchase Invoice (PI) cicilan aset - * secara otomatis setiap bulan berdasarkan kontrak yang aktif. + * CRON scheduler untuk membuat baris cicilan otomatis ke tabel supplier_installment + * setiap bulan berdasarkan kontrak aset yang aktif dan belum lunas. * - * Endpoint utama: + * Endpoint: * POST /scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices - * POST /scheduler/PurchaseInvoiceInstallment/CurlGenerateMonthlyInvoices */ class PurchaseInvoiceInstallment extends MY_Controller { var $db; - var $baseUrl = "https://accone.aplikasi.web.id/one-api/"; + public function index() { - echo "Purchase Invoice Installment — Auto Generate PI Cicilan Aset"; + echo "Purchase Invoice Installment — Auto Generate Installment Cicilan Aset"; } public function __construct() @@ -25,327 +24,121 @@ class PurchaseInvoiceInstallment extends MY_Controller } /** - * GenerateMonthlyInvoices + * GenerateMonthlyInvoices — Step 6 * - * Membuat Purchase Invoice cicilan untuk semua kontrak aset yang aktif - * dan belum lunas pada bulan yang ditentukan. + * Creates supplier_installment rows for all eligible contracts this month. + * No journal is created here — that happens at cashier payment time. + * Contract InstallmentPaid is NOT updated here — that happens at payment time. * - * Parameter (POST JSON): - * - startDate : Tanggal awal periode (format YYYY-MM-DD). Default: awal bulan ini. - * - endDate : Tanggal akhir periode (format YYYY-MM-DD). Default: akhir bulan ini. - * userID diambil otomatis dari token (sys_user["M_UserID"]). - * Jika CRON berjalan tanpa token, fallback ke user ID 0. - * - * Syarat kontrak diproses: - * 1. Kontrak aktif dan berstatus "belum lunas" - * 2. Nilai cicilan > 0 - * 3. Jumlah cicilan terbayar < total cicilan - * 4. Tanggal kontrak masuk dalam bulan yang dituju - * 5. RO sudah confirmed - * 6. PO sudah berstatus Approved + * Called by CRON daily at 1:00 AM. + * Defaults to current month if no startDate/endDate provided. */ public function GenerateMonthlyInvoices() { try { - $para = $this->sys_input; - // Ambil userID dari token JWT (sys_user). Fallback ke 0 jika CRON berjalan tanpa token. - $userID = !empty($this->sys_user["M_UserID"]) ? (int) $this->sys_user["M_UserID"] : 0; - $user = $this->getCronUser($userID); + $para = $this->sys_input; - $startDate = isset($para["startDate"]) && $para["startDate"] != "" + $userID = !empty($this->sys_user["M_UserID"]) + ? (int) $this->sys_user["M_UserID"] + : 0; + + $startDate = !empty($para["startDate"]) ? $para["startDate"] - : (isset($para["date"]) && $para["date"] != "" ? date("Y-m-01", strtotime($para["date"])) : date("Y-m-01")); - $endDate = isset($para["endDate"]) && $para["endDate"] != "" + : date("Y-m-01"); + + $endDate = !empty($para["endDate"]) ? $para["endDate"] - : (isset($para["date"]) && $para["date"] != "" ? date("Y-m-t", strtotime($para["date"])) : date("Y-m-t")); - // Validasi format tanggal + : date("Y-m-t"); + if (!$this->isValidDate($startDate) || !$this->isValidDate($endDate)) { - throw new Exception("Format tanggal tidak valid. Gunakan format YYYY-MM-DD, contoh: 2025-07-01"); + throw new Exception("Format tanggal tidak valid."); } if (strtotime($startDate) > strtotime($endDate)) { - throw new Exception("startDate tidak boleh lebih besar dari endDate"); + throw new Exception("startDate > endDate."); } - // Tentukan rentang bulan berdasarkan tanggal acuan - $monthStart = $startDate; - $monthEnd = $endDate; - $dayOfMonth = (int) date("d", strtotime($endDate)); + // ── Steps 1–5: Get eligible contracts ──────────────────── + $eligible = $this->getEligibleInstallments($startDate, $endDate); - // ------------------------------------------------------------------------- - // Ambil semua kontrak cicilan yang memenuhi syarat pada bulan ini - // ------------------------------------------------------------------------- - $sqlKontrak = "SELECT - c.PurchaseOrderAssetContractID, - c.PurchaseOrderAssetContractPurchaseOrderID, - ro.ReceiveOrderPoID AS PurchaseOrderAssetContractReceiveOrderPoID, - c.PurchaseOrderAssetContractName, - c.PurchaseOrderAssetContractStartDate, - c.PurchaseOrderAssetContractEndDate, - c.PurchaseOrderAssetContractInstallmentNumber, - c.PurchaseOrderAssetContractInstallmentPaid, - c.PurchaseOrderAssetContractInstallmentDate, - c.PurchaseOrderAssetContractInstallmentPayAmount, - c.PurchaseOrderAssetContractCreatedUserID, - po.PurchaseOrderID, - po.PurchaseOrderNumber, - po.PurchaseOrderSupplierID, - po.PurchaseOrderPaymentTerm, - po.PurchaseOrderWarehouseType, - po.PurchaseOrderWarehouseID, - ro.ReceiveOrderPoConfirmed, - ps.PurchaseOrderSummaryID, - ps.PurchaseOrderSummaryItemID, - ps.PurchaseOrderSummaryItemUnitID - FROM purchase_order_asset_contract c + $created = []; + $inserted = 0; - -- Pastikan PO sudah Approved dan aktif - JOIN purchase_order po - ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID - AND po.PurchaseOrderIsActive = 'Y' - AND po.PurchaseOrderStatus = 'Approved' + $this->db->trans_begin(); - JOIN ( - SELECT - rd.ReceiveOrderPoDetailPurchaseOrderID, - MIN(ro0.ReceiveOrderPoID) AS ReceiveOrderPoID, - MAX(ro0.ReceiveOrderPoConfirmed) AS ReceiveOrderPoConfirmed - FROM receive_order_po ro0 - JOIN receive_order_po_detail rd - ON rd.ReceiveOrderPoDetailReceiveOrderPoID = ro0.ReceiveOrderPoID - AND rd.ReceiveOrderPoDetailIsActive = 'Y' - WHERE ro0.ReceiveOrderPoIsActive = 'Y' - AND ro0.ReceiveOrderPoConfirmed = 'Y' - GROUP BY rd.ReceiveOrderPoDetailPurchaseOrderID - ) ro - ON ro.ReceiveOrderPoDetailPurchaseOrderID = po.PurchaseOrderID + foreach ($eligible as $row) { - -- Ambil 1 item PO pertama sebagai referensi baris detail PI - LEFT JOIN ( - SELECT ps0.* - FROM purchase_order_summary ps0 - JOIN ( - SELECT - PurchaseOrderSummaryPurchaseOrderID, - MIN(PurchaseOrderSummaryID) AS PurchaseOrderSummaryID - FROM purchase_order_summary - WHERE PurchaseOrderSummaryIsActive = 'Y' - GROUP BY PurchaseOrderSummaryPurchaseOrderID - ) psx - ON psx.PurchaseOrderSummaryID = ps0.PurchaseOrderSummaryID - ) ps - ON ps.PurchaseOrderSummaryPurchaseOrderID = po.PurchaseOrderID + $amount = (float) $row["PurchaseOrderAssetContractInstallmentPayAmount"]; + $dayOfMonth = (int) ($row["PurchaseOrderAssetContractInstallmentDate"] ?? 1); + $lastDay = (int) date("t", strtotime($endDate)); + $dayOfMonth = min($dayOfMonth, $lastDay); + $installDate = date("Y-m", strtotime($endDate)) . "-" . str_pad($dayOfMonth, 2, "0", STR_PAD_LEFT); + $dueDate = date("Y-m-d", strtotime($installDate . " +7 days")); + $createdBy = (int) ($row["PurchaseOrderAssetContractCreatedUserID"] ?? $userID); - WHERE c.PurchaseOrderAssetContractIsActive = 'Y' - AND c.PurchaseOrderAssetContractStatus = 'belum lunas' - -- Hanya kontrak yang ada nilai cicilannya - AND IFNULL(c.PurchaseOrderAssetContractInstallmentPayAmount, 0) > 0 - -- Hanya kontrak yang belum selesai seluruh cicilannya - AND IFNULL(c.PurchaseOrderAssetContractInstallmentPaid, 0) < IFNULL(c.PurchaseOrderAssetContractInstallmentNumber, 0) - -- Kontrak sudah mulai sebelum atau pada akhir bulan ini - AND DATE(c.PurchaseOrderAssetContractStartDate) <= DATE(?) - -- Kontrak belum berakhir (atau tidak ada tanggal akhir) - AND ( - c.PurchaseOrderAssetContractEndDate IS NULL - OR DATE(c.PurchaseOrderAssetContractEndDate) >= DATE(?) - ) - -- Tanggal jatuh tempo cicilan sudah melewati atau sama dengan hari ini - AND IFNULL(c.PurchaseOrderAssetContractInstallmentDate, 1) <= ?"; + // ── Step 6: INSERT supplier_installment ────────────── + $sql = "INSERT INTO supplier_installment ( + SupplierInstallmentPurchaseOrderID, + SupplierInstallmentSupplierID, + SupplierInstallmentSupplierInvoiceID, + SupplierInstallmentAmount, + SupplierInstallmentDate, + SupplierInstallmentDueDate, + SupplierInstallmentPaymentID, + SupplierInstallmentStatus, + SupplierInstallmentIsLunas, + SupplierInstallmentIsActive, + SupplierInstallmentCreated, + SupplierInstallmentCreatedUserID + ) VALUES (?, ?, ?, ?, ?, ?, 0, 'Pending', 'N', 'Y', NOW(), ?)"; - $params = [$monthEnd, $monthStart, $dayOfMonth]; + $que = $this->db->query($sql, [ + $row["PurchaseOrderID"], + $row["PurchaseOrderSupplierID"], + $row["SupplierInvoiceID"], + $amount, + $installDate, + $dueDate, + $createdBy + ]); - $qryKontrak = $this->db->query($sqlKontrak, $params); - if (!$qryKontrak) { - $this->sys_error_db("Gagal mengambil daftar kontrak cicilan dari database."); + if (!$que) { + $this->db->trans_rollback(); + $this->sys_error_db("Gagal insert supplier_installment."); + exit; + } + + $installmentID = $this->db->insert_id(); + $inserted++; + + $created[] = [ + "installmentID" => $installmentID, + "contractID" => $row["PurchaseOrderAssetContractID"], + "purchaseOrderID" => $row["PurchaseOrderID"], + "parentInvoiceID" => $row["SupplierInvoiceID"], + "parentInvoiceNumber" => $row["SupplierInvoiceNumber"], + "amount" => $amount, + "installDate" => $installDate, + "dueDate" => $dueDate + ]; + } + + if ($this->db->trans_status() === false) { + $this->db->trans_rollback(); + $this->sys_error_db("Transaksi gagal."); exit; } - $berhasil = []; // PI yang berhasil dibuat - $dilewati = []; // PI yang dilewati beserta alasannya + $this->db->trans_commit(); - // ------------------------------------------------------------------------- - // Proses tiap kontrak satu per satu - // ------------------------------------------------------------------------- - $kontraks = $qryKontrak->result_array(); - foreach ($kontraks as $kontrak) { - - // Lewati jika item/satuan PO tidak ditemukan (tidak bisa buat baris detail) - if (empty($kontrak["PurchaseOrderSummaryItemID"]) || empty($kontrak["PurchaseOrderSummaryItemUnitID"])) { - $dilewati[] = [ - "kontrakID" => $kontrak["PurchaseOrderAssetContractID"], - "purchaseOrderID" => $kontrak["PurchaseOrderID"], - "alasan" => "Item atau satuan pada Purchase Order tidak ditemukan, tidak bisa membuat baris detail PI." - ]; - continue; - } - - // ------------------------------------------------------- - // Cek apakah PI cicilan bulan ini sudah pernah dibuat - // ------------------------------------------------------- - $sqlCekDuplikat = "SELECT SupplierInvoiceID, SupplierInvoiceNumber - FROM supplier_invoice - WHERE SupplierInvoiceIsActive = 'Y' - AND SupplierInvoiceDate >= DATE(?) - AND SupplierInvoiceDate <= DATE(?) - AND SupplierInvoiceStatus = 'Draft' - AND ( - SupplierInvoiceReceiveOrderPoID = ? - OR EXISTS ( - SELECT 1 - FROM supplier_invoice_detail sid - WHERE sid.SupplierInvoiceDetailSupplierInvoiceID = SupplierInvoiceID - AND sid.SupplierInvoiceDetailReceiveOrderPoID = ? - AND sid.SupplierInvoiceDetailIsActive = 'Y' - ) - ) - LIMIT 1"; - - $qryCekDuplikat = $this->db->query($sqlCekDuplikat, [ - $monthStart, - $monthEnd, - $kontrak["PurchaseOrderAssetContractReceiveOrderPoID"], - $kontrak["PurchaseOrderAssetContractReceiveOrderPoID"] - ]); - - if (!$qryCekDuplikat) { - $this->sys_error_db("Gagal memeriksa duplikasi PI cicilan untuk kontrak ID " . $kontrak["PurchaseOrderAssetContractID"] . "."); - exit; - } - - if ($qryCekDuplikat->num_rows() > 0) { - $piExisting = $qryCekDuplikat->row_array(); - $dilewati[] = [ - "kontrakID" => $kontrak["PurchaseOrderAssetContractID"], - "purchaseOrderID" => $kontrak["PurchaseOrderID"], - "receiveOrderPoID" => $kontrak["PurchaseOrderAssetContractReceiveOrderPoID"], - "supplierInvoiceID" => $piExisting["SupplierInvoiceID"], - "nomorInvoice" => $piExisting["SupplierInvoiceNumber"], - "alasan" => "PI cicilan untuk bulan ini sudah dibuat sebelumnya, tidak perlu dibuat ulang." - ]; - continue; - } - - $contractUserID = (int) ($kontrak["PurchaseOrderAssetContractCreatedUserID"] ?? 0); - $contractUser = $this->getCronUser($contractUserID); - - // Generate nomor PI otomatis via stored function fn_penomoran - $nomorPI = $this->generateNomorPI($kontrak, $contractUser); - - $jumlahCicilan = (float) $kontrak["PurchaseOrderAssetContractInstallmentPayAmount"]; - $paymentTerm = isset($kontrak["PurchaseOrderPaymentTerm"]) && $kontrak["PurchaseOrderPaymentTerm"] !== null - ? (int) $kontrak["PurchaseOrderPaymentTerm"] - : 0; - $tanggalJatuhTempo = $this->hitungJatuhTempo($endDate, $paymentTerm); - $catatan = "PI Cicilan Otomatis — Kontrak Aset ID " . $kontrak["PurchaseOrderAssetContractID"] . " periode " . date("Y-m", strtotime($startDate)); - - // ------------------------------------------------------- - // INSERT header + detail Purchase Invoice (supplier_invoice & supplier_invoice_detail) - // ------------------------------------------------------- - $deskripsi = $kontrak["PurchaseOrderAssetContractName"] != "" - ? $kontrak["PurchaseOrderAssetContractName"] - : "Cicilan Kontrak Aset ID " . $kontrak["PurchaseOrderAssetContractID"]; - $deskripsi .= " periode " . date("Y-m", strtotime($startDate)); - - $payloadInsert = [ - "nomorPI" => $nomorPI, - "tanggalPI" => $endDate, - "tanggalJatuhTempo" => $tanggalJatuhTempo, - "jumlahCicilan" => $jumlahCicilan, - "catatan" => $catatan, - "deskripsi" => $deskripsi, - "userID" => $contractUserID, - "purchaseOrderAssetContractID" => $kontrak["PurchaseOrderAssetContractID"], - "purchaseOrderID" => $kontrak["PurchaseOrderID"], - "receiveOrderPoID" => $kontrak["PurchaseOrderAssetContractReceiveOrderPoID"], - "supplierID" => $kontrak["PurchaseOrderSupplierID"], - "purchaseOrderSummaryID" => $kontrak["PurchaseOrderSummaryID"], - "purchaseOrderSummaryItemID" => $kontrak["PurchaseOrderSummaryItemID"], - "purchaseOrderSummaryItemUnitID" => $kontrak["PurchaseOrderSummaryItemUnitID"] - ]; - - $hasilInsert = $this->curlInsertSupplierInvoice($payloadInsert); - if ($hasilInsert === false) { - $this->sys_error_db("Gagal menyimpan Purchase Invoice cicilan untuk kontrak ID " . $kontrak["PurchaseOrderAssetContractID"] . "."); - exit; - } - - if (!empty($hasilInsert["duplicate"])) { - $dilewati[] = [ - "kontrakID" => $kontrak["PurchaseOrderAssetContractID"], - "purchaseOrderID" => $kontrak["PurchaseOrderID"], - "receiveOrderPoID" => $kontrak["PurchaseOrderAssetContractReceiveOrderPoID"], - "supplierInvoiceID" => $hasilInsert["supplierInvoiceID"], - "nomorInvoice" => $hasilInsert["supplierInvoiceNumber"], - "alasan" => "PI cicilan untuk bulan ini sudah dibuat sebelumnya, tidak perlu dibuat ulang." - ]; - continue; - } - - $supplierInvoiceID = $hasilInsert["supplierInvoiceID"]; - - // ------------------------------------------------------- - // UPDATE jumlah cicilan terbayar pada kontrak - // ------------------------------------------------------- - $this->db->trans_begin(); - - $cicilanTerbayarBaru = ((int) $kontrak["PurchaseOrderAssetContractInstallmentPaid"]) + 1; - $statusKontrakBaru = $cicilanTerbayarBaru >= (int) $kontrak["PurchaseOrderAssetContractInstallmentNumber"] - ? "lunas" - : "belum lunas"; - - $sqlUpdateKontrak = "UPDATE purchase_order_asset_contract - SET PurchaseOrderAssetContractReceiveOrderPoID = ?, - PurchaseOrderAssetContractInstallmentPaid = ?, - PurchaseOrderAssetContractStatus = ?, - PurchaseOrderAssetContractLastUpdated = NOW() - WHERE PurchaseOrderAssetContractID = ? - AND PurchaseOrderAssetContractIsActive = 'Y'"; - - $qryUpdateKontrak = $this->db->query($sqlUpdateKontrak, [ - $kontrak["PurchaseOrderAssetContractReceiveOrderPoID"], - $cicilanTerbayarBaru, - $statusKontrakBaru, - $kontrak["PurchaseOrderAssetContractID"] - ]); - - if (!$qryUpdateKontrak) { - $this->db->trans_rollback(); - $this->sys_error_db("Gagal memperbarui data cicilan terbayar pada kontrak ID " . $kontrak["PurchaseOrderAssetContractID"] . "."); - exit; - } - - // Pastikan tidak ada error di dalam transaksi sebelum commit - if ($this->db->trans_status() === false) { - $this->db->trans_rollback(); - $this->sys_error_db("Transaksi database gagal saat memproses kontrak ID " . $kontrak["PurchaseOrderAssetContractID"] . ". Semua perubahan dibatalkan."); - exit; - } - - $this->db->trans_commit(); - - // Catat PI yang berhasil dibuat - $berhasil[] = [ - "kontrakID" => $kontrak["PurchaseOrderAssetContractID"], - "purchaseOrderID" => $kontrak["PurchaseOrderID"], - "supplierInvoiceID" => $supplierInvoiceID, - "nomorInvoice" => $nomorPI, - "jumlahCicilan" => $jumlahCicilan - ]; - } - - // ------------------------------------------------------- - // Response sukses — ringkasan hasil proses - // ------------------------------------------------------- $this->sys_ok([ "startDate" => $startDate, "endDate" => $endDate, - "periodeAwal" => $monthStart, - "periodeAkhir" => $monthEnd, - "totalDibuat" => count($berhasil), - "totalDilewati" => count($dilewati), - "daftarDibuat" => $berhasil, - "daftarDilewati" => $dilewati + "totalEligible" => count($eligible), + "totalInserted" => $inserted, + "created" => $created ]); + } catch (Exception $exc) { if ($this->db->trans_status() === false) { $this->db->trans_rollback(); @@ -354,229 +147,6 @@ class PurchaseInvoiceInstallment extends MY_Controller } } - /** - * Kirim payload insert supplier_invoice ke controller terpisah via cURL. - * - * @param array $payload - * @return array|false - */ - private function curlInsertSupplierInvoice($payload) - { - $endpoint = rtrim($this->baseUrl, "/") . "/mockup/scheduler/PurchaseInvoiceInstallmentInsert/InsertSupplierInvoice"; - - $ch = curl_init($endpoint); - curl_setopt_array($ch, [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_POST => true, - CURLOPT_HTTPHEADER => [ - "Content-Type: application/json", - "Accept: application/json" - ], - CURLOPT_POSTFIELDS => json_encode($payload), - CURLOPT_CONNECTTIMEOUT => 15, - CURLOPT_TIMEOUT => 120 - ]); - - $response = curl_exec($ch); - if (curl_errno($ch)) { - $pesanError = curl_error($ch); - curl_close($ch); - $this->sys_error("Gagal menghubungi endpoint insert supplier_invoice. Detail: " . $pesanError); - return false; - } - - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - - if ($httpCode < 200 || $httpCode >= 300) { - $this->sys_error("Endpoint insert supplier_invoice mengembalikan HTTP " . $httpCode . "."); - return false; - } - - $decoded = json_decode($response, true); - if (!is_array($decoded)) { - $this->sys_error("Response insert supplier_invoice tidak valid JSON."); - return false; - } - - if (!isset($decoded["status"]) || strtoupper($decoded["status"]) !== "OK") { - $pesan = isset($decoded["message"]) ? $decoded["message"] : "Insert supplier_invoice gagal."; - $this->sys_error($pesan); - return false; - } - - return isset($decoded["data"]) && is_array($decoded["data"]) ? $decoded["data"] : $decoded; - } - - public function ListEligibleContracts() - { - try { - $para = $this->sys_input; - $startDate = isset($para["startDate"]) && $para["startDate"] != "" - ? $para["startDate"] - : (isset($para["date"]) && $para["date"] != "" ? date("Y-m-01", strtotime($para["date"])) : date("Y-m-01")); - $endDate = isset($para["endDate"]) && $para["endDate"] != "" - ? $para["endDate"] - : (isset($para["date"]) && $para["date"] != "" ? date("Y-m-t", strtotime($para["date"])) : date("Y-m-t")); - - if (!$this->isValidDate($startDate) || !$this->isValidDate($endDate)) { - throw new Exception("Format tanggal tidak valid. Gunakan format YYYY-MM-DD, contoh: 2025-07-01"); - } - - if (strtotime($startDate) > strtotime($endDate)) { - throw new Exception("startDate tidak boleh lebih besar dari endDate"); - } - - $monthStart = $startDate; - $monthEnd = $endDate; - $dayOfMonth = (int) date("d", strtotime($endDate)); - - $sqlKontrak = "SELECT - c.PurchaseOrderAssetContractID, - c.PurchaseOrderAssetContractPurchaseOrderID, - ro.ReceiveOrderPoID AS PurchaseOrderAssetContractReceiveOrderPoID, - c.PurchaseOrderAssetContractName, - c.PurchaseOrderAssetContractStartDate, - c.PurchaseOrderAssetContractEndDate, - c.PurchaseOrderAssetContractInstallmentNumber, - c.PurchaseOrderAssetContractInstallmentPaid, - c.PurchaseOrderAssetContractInstallmentDate, - c.PurchaseOrderAssetContractInstallmentPayAmount, - po.PurchaseOrderID, - po.PurchaseOrderNumber, - po.PurchaseOrderSupplierID, - po.PurchaseOrderPaymentTerm, - po.PurchaseOrderWarehouseType, - po.PurchaseOrderWarehouseID, - ro.ReceiveOrderPoConfirmed, - ps.PurchaseOrderSummaryID, - ps.PurchaseOrderSummaryItemID, - ps.PurchaseOrderSummaryItemUnitID - FROM purchase_order_asset_contract c - JOIN purchase_order po - ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID - AND po.PurchaseOrderIsActive = 'Y' - AND po.PurchaseOrderStatus = 'Approved' - - JOIN ( - SELECT - rd.ReceiveOrderPoDetailPurchaseOrderID, - MIN(ro0.ReceiveOrderPoID) AS ReceiveOrderPoID, - MAX(ro0.ReceiveOrderPoConfirmed) AS ReceiveOrderPoConfirmed - FROM receive_order_po ro0 - JOIN receive_order_po_detail rd - ON rd.ReceiveOrderPoDetailReceiveOrderPoID = ro0.ReceiveOrderPoID - AND rd.ReceiveOrderPoDetailIsActive = 'Y' - WHERE ro0.ReceiveOrderPoIsActive = 'Y' - AND ro0.ReceiveOrderPoConfirmed = 'Y' - GROUP BY rd.ReceiveOrderPoDetailPurchaseOrderID - ) ro - ON ro.ReceiveOrderPoDetailPurchaseOrderID = po.PurchaseOrderID - - LEFT JOIN ( - SELECT ps0.* - FROM purchase_order_summary ps0 - JOIN ( - SELECT - PurchaseOrderSummaryPurchaseOrderID, - MIN(PurchaseOrderSummaryID) AS PurchaseOrderSummaryID - FROM purchase_order_summary - WHERE PurchaseOrderSummaryIsActive = 'Y' - GROUP BY PurchaseOrderSummaryPurchaseOrderID - ) psx - ON psx.PurchaseOrderSummaryID = ps0.PurchaseOrderSummaryID - ) ps - ON ps.PurchaseOrderSummaryPurchaseOrderID = po.PurchaseOrderID - WHERE c.PurchaseOrderAssetContractIsActive = 'Y' - AND c.PurchaseOrderAssetContractStatus = 'belum lunas' - AND IFNULL(c.PurchaseOrderAssetContractInstallmentPayAmount, 0) > 0 - AND IFNULL(c.PurchaseOrderAssetContractInstallmentPaid, 0) < IFNULL(c.PurchaseOrderAssetContractInstallmentNumber, 0) - AND DATE(c.PurchaseOrderAssetContractStartDate) <= DATE(?) - AND ( - c.PurchaseOrderAssetContractEndDate IS NULL - OR DATE(c.PurchaseOrderAssetContractEndDate) >= DATE(?) - ) - AND IFNULL(c.PurchaseOrderAssetContractInstallmentDate, 1) <= ? - ORDER BY c.PurchaseOrderAssetContractID ASC"; - - $qryKontrak = $this->db->query($sqlKontrak, [$monthEnd, $monthStart, $dayOfMonth]); - if (!$qryKontrak) { - $this->sys_error_db("Gagal mengambil daftar kontrak cicilan eligible."); - exit; - } - - $this->sys_ok([ - "startDate" => $startDate, - "endDate" => $endDate, - "periodeAwal" => $monthStart, - "periodeAkhir" => $monthEnd, - "total" => $qryKontrak->num_rows(), - "records" => $qryKontrak->result_array() - ]); - } catch (Exception $exc) { - $this->sys_error($exc->getMessage()); - } - } - - /** - * CurlGenerateMonthlyInvoices - * - * Wrapper untuk memanggil GenerateMonthlyInvoices melalui HTTP request (cURL). - * Cocok digunakan oleh CRON eksternal yang tidak bisa memanggil function PHP langsung. - * - * Parameter (POST JSON): - * - baseUrl : Base URL server tujuan. Default: URL server ini sendiri. - * - startDate : Tanggal awal periode (YYYY-MM-DD). Default: awal bulan ini. - * - endDate : Tanggal akhir periode (YYYY-MM-DD). Default: akhir bulan ini. - * - userID : ID user yang menjalankan. Default: 0. - */ - - // ========================================================================= - // FUNGSI PRIVATE / HELPER - // ========================================================================= - - /** - * Generate nomor Purchase Invoice. - * - * @param array $kontrak Data baris kontrak dari query - * @param array $user Data user CRON - * @return string Nomor PI yang dihasilkan - */ - private function generateNomorPI($kontrak, $user) - { - $userID = isset($user["M_UserID"]) ? (int) $user["M_UserID"] : 0; - - // Tentukan area ID dan type - $areaid = isset($user["M_BranchID"]) && (int) $user["M_BranchID"] > 0 ? (int) $user["M_BranchID"] : 0; - $areatype = 'B'; - if (isset($user["loginLevel"]) && $user["loginLevel"] == 'regional') { - $areaid = isset($user["S_RegionalID"]) && (int) $user["S_RegionalID"] > 0 ? (int) $user["S_RegionalID"] : 0; - $areatype = 'R'; - } - - // Ambil divisi user - $userDivID = 0; - if ($userID > 0) { - $sqlusrdivisi = "SELECT M_UserDivisionDivisionID FROM m_userdivision - WHERE M_UserDivisionM_UserID = ? AND M_UserDivisionIsActive = 'Y' LIMIT 1"; - $queusrdivisi = $this->db->query($sqlusrdivisi, [$userID]); - if ($queusrdivisi && $queusrdivisi->num_rows() > 0) { - $userDivID = (int) $queusrdivisi->row_array()['M_UserDivisionDivisionID']; - } - } - - // Jalankan stored function fn_penomoran - $sqlnum = "SELECT `fn_penomoran`(?, ?, ?, ?, ?, ?) AS numpd;"; - $quenum = $this->db->query($sqlnum, ['PI', $userDivID, $areatype, $areaid, 'SM', 'N']); - if ($quenum && $quenum->num_rows() > 0) { - return $quenum->row_array()['numpd']; - } - - // Fallback jika stored function gagal - $contractID = isset($kontrak["PurchaseOrderAssetContractID"]) ? (int) $kontrak["PurchaseOrderAssetContractID"] : 0; - return "PI-INS-FALLBACK-" . $contractID . "-" . date("Ymd"); - } - /** * Ambil data user berdasarkan userID untuk keperluan CRON. * Jika user tidak ditemukan, kembalikan data default (tanpa branch/regional). @@ -638,4 +208,95 @@ class PurchaseInvoiceInstallment extends MY_Controller $d = DateTime::createFromFormat("Y-m-d", $tanggal); return $d && $d->format("Y-m-d") === $tanggal; } + + /** + * getEligibleInstallments — Steps 1–5 combined + * + * Returns contracts that: + * Step 1: Are active, not paid off, within date range, due date reached + * Step 2: Have approved & active PO + * Step 3: Have confirmed & active RO + * Step 4: Have a parent supplier_invoice with IsInstallment = 'Y' + * Step 5: Do NOT already have a supplier_installment for this month + * + * @param string $startDate YYYY-MM-DD + * @param string $endDate YYYY-MM-DD + * @return array + */ + private function getEligibleInstallments($startDate, $endDate) + { + $dayOfMonth = (int) date("d", strtotime($endDate)); + + $sql = "SELECT + c.PurchaseOrderAssetContractID, + c.PurchaseOrderAssetContractInstallmentPayAmount, + c.PurchaseOrderAssetContractInstallmentDate, + c.PurchaseOrderAssetContractCreatedUserID, + po.PurchaseOrderID, + po.PurchaseOrderSupplierID, + si.SupplierInvoiceID, + si.SupplierInvoiceNumber + FROM purchase_order_asset_contract c + + -- Step 2: PO must be Approved and Active + JOIN purchase_order po + ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID + AND po.PurchaseOrderIsActive = 'Y' + AND po.PurchaseOrderStatus = 'Approved' + + -- Step 3: RO must be Confirmed and Active + JOIN ( + SELECT + rd.ReceiveOrderPoDetailPurchaseOrderID, + MIN(ro0.ReceiveOrderPoID) AS ReceiveOrderPoID, + MAX(ro0.ReceiveOrderPoConfirmed) AS ReceiveOrderPoConfirmed + FROM receive_order_po ro0 + JOIN receive_order_po_detail rd + ON rd.ReceiveOrderPoDetailReceiveOrderPoID = ro0.ReceiveOrderPoID + AND rd.ReceiveOrderPoDetailIsActive = 'Y' + WHERE ro0.ReceiveOrderPoIsActive = 'Y' + AND ro0.ReceiveOrderPoConfirmed = 'Y' + GROUP BY rd.ReceiveOrderPoDetailPurchaseOrderID + ) ro ON ro.ReceiveOrderPoDetailPurchaseOrderID = po.PurchaseOrderID + + -- Step 4: Parent invoice must exist with IsInstallment = 'Y' + JOIN supplier_invoice si + ON si.SupplierInvoiceReceiveOrderPoID = ro.ReceiveOrderPoID + AND si.SupplierInvoiceIsActive = 'Y' + AND si.SupplierInvoiceIsInstallment = 'Y' + + -- Step 1: Contract eligibility + WHERE c.PurchaseOrderAssetContractIsActive = 'Y' + AND c.PurchaseOrderAssetContractStatus = 'belum lunas' + AND IFNULL(c.PurchaseOrderAssetContractInstallmentPayAmount, 0) > 0 + AND IFNULL(c.PurchaseOrderAssetContractInstallmentPaid, 0) + < IFNULL(c.PurchaseOrderAssetContractInstallmentNumber, 0) + AND DATE(c.PurchaseOrderAssetContractStartDate) <= DATE(?) + AND ( + c.PurchaseOrderAssetContractEndDate IS NULL + OR DATE(c.PurchaseOrderAssetContractEndDate) >= DATE(?) + ) + AND IFNULL(c.PurchaseOrderAssetContractInstallmentDate, 1) <= ? + + -- Step 5: Dedup — no existing supplier_installment this month (any status) + AND NOT EXISTS ( + SELECT 1 + FROM supplier_installment inst + WHERE inst.SupplierInstallmentIsActive = 'Y' + AND inst.SupplierInstallmentPurchaseOrderID = po.PurchaseOrderID + AND DATE_FORMAT(inst.SupplierInstallmentDate, '%Y-%m') = DATE_FORMAT(?, '%Y-%m') + ) + + ORDER BY c.PurchaseOrderAssetContractID ASC"; + + $params = [$endDate, $startDate, $dayOfMonth, $endDate]; + + $qry = $this->db->query($sql, $params); + if (!$qry) { + $this->sys_error_db("Gagal mengambil daftar installment eligible."); + exit; + } + + return $qry->result_array(); + } } diff --git a/application/controllers/mockup/supplierpaymentapprovedv3/Billv2.php b/application/controllers/mockup/supplierpaymentapprovedv3/Billv2.php index cbb9658..46b879b 100644 --- a/application/controllers/mockup/supplierpaymentapprovedv3/Billv2.php +++ b/application/controllers/mockup/supplierpaymentapprovedv3/Billv2.php @@ -28,7 +28,7 @@ class Billv2 extends MY_Controller { $offset = ($params['currentpage'] - 1) * $limit; } - // ── UNION base — invoice branch + downpayment branch ──── + // ── UNION base — invoice + downpayment + installment ─── $sql_base = " SELECT sp.SupplierPaymentID, @@ -76,7 +76,33 @@ class Billv2 extends MY_Controller { ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID JOIN purchase_order po ON po.PurchaseOrderID = dp.SupplierDownpaymentPurchasOrderID - WHERE sp.SupplierPaymentSupplierDownpaymentID IS NOT NULL"; + 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 = " @@ -97,8 +123,7 @@ class Billv2 extends MY_Controller { } // ── COUNT — wrap UNION in outer filter ────────────────── - $sql_total = " - SELECT COUNT(*) AS total FROM ($sql_base) AS combined + $sql_total = "SELECT COUNT(*) AS total FROM ($sql_base) AS combined WHERE SupplierPaymentIsActive = 'Y' AND SupplierPaymentNumber LIKE ? AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?)) @@ -118,7 +143,6 @@ class Billv2 extends MY_Controller { ]; $this->sys_ok($output); - exit; } catch (Exception $exc) { $message = $exc->getMessage(); $code = $exc->getCode(); @@ -143,7 +167,8 @@ class Billv2 extends MY_Controller { // ── Detect payment type ────────────────────────────────── $sql_type = "SELECT SupplierPaymentSupplierInvoiceID, - SupplierPaymentSupplierDownpaymentID + SupplierPaymentSupplierDownpaymentID, + SupplierPaymentSupplierInstallmentID FROM supplier_payment WHERE SupplierPaymentID = ? AND SupplierPaymentIsActive = 'Y'"; @@ -206,7 +231,7 @@ class Billv2 extends MY_Controller { $data['detail'] = $que_detail->result_array(); // ── DOWNPAYMENT branch ────────────────────────────────── - } else { + } elseif ($payment['SupplierPaymentSupplierDownpaymentID'] > 0) { $sql = "SELECT dp.SupplierDownpaymentPurchasOrderID, dp.SupplierDownpaymentAmount AS SupplierInvoiceSubTotal, @@ -255,6 +280,51 @@ class Billv2 extends MY_Controller { 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(); } diff --git a/application/controllers/mockup/supplierpaymentcashierv5/Bill.php b/application/controllers/mockup/supplierpaymentcashierv5/Bill.php index 2cb05dc..8620f5b 100644 --- a/application/controllers/mockup/supplierpaymentcashierv5/Bill.php +++ b/application/controllers/mockup/supplierpaymentcashierv5/Bill.php @@ -121,9 +121,86 @@ class Bill extends MY_Controller } } + public function add_notes_installment($orderid) + { + $sql = "SELECT SupplierPaymentSupplierInstallmentID as note_order_id, + SupplierPaymentID as note_id, + SupplierInstallmentID as detail_id, + SupplierPaymentDate as note_date, + SupplierPaymentNumber as note_number, + GROUP_CONCAT(DISTINCT coaDescription separator ' , ') as paymenttypes_name, + SUM(SupplierInstallmentAmount) as note_amount, + n.M_UserUsername as note_user, + SupplierInstallmentIsActive as note_active, + 'N' as show_detail, + SupplierPaymentNote as keterangan, + SupplierPaymentCoaID, + coaID, + coaDescription, + SupplierPaymentIsConfirm, + CONCAT( + 'Confirmed by : ',c.M_UserUsername, ' ', + DATE_FORMAT(SupplierPaymentConfirmDate,'%d-%m-%Y %H:%i') + ) AS d_confirm, + SupplierPaymentIsApproved, + CONCAT( + 'Approved by : ',a.M_UserUsername, ' ', + DATE_FORMAT(SupplierPaymentApprovedDate,'%d-%m-%Y %H:%i') + ) AS d_approved, + CONCAT( + 'Verified by : ',b.M_UserUsername, ' ', + DATE_FORMAT(SupplierPaymentVerifDate,'%d-%m-%Y %H:%i') + ) AS d_verif + FROM supplier_payment + JOIN supplier_installment + ON SupplierInstallmentID = SupplierPaymentSupplierInstallmentID + AND SupplierInstallmentIsActive = 'Y' + LEFT JOIN coa ON SupplierPaymentCoaID = coaID + LEFT JOIN m_user n ON SupplierPaymentUserID = n.M_UserID + LEFT JOIN m_user c ON SupplierPaymentConfirmUserID = c.M_UserID + LEFT JOIN m_user a ON SupplierPaymentApprovedUserID = a.M_UserID + LEFT JOIN m_user b ON SupplierPaymentVerifUserID = b.M_UserID + WHERE SupplierPaymentSupplierInstallmentID = {$orderid} + AND SupplierPaymentIsActive = 'Y' + GROUP BY SupplierPaymentID"; + $query = $this->db_onedev->query($sql); + if ($query) { + $rows = $query->result_array(); + return $rows ?: []; + } else { + $this->sys_error_db("get Installment notes", $this->db_onedev); + exit; + } + } + public function add_tagihans($orderid) { - $sql = "SELECT SupplierInvoiceID as tagihan_id, + $sql_dp = "SELECT + Fa_ClassDownPaymentCoaID + FROM supplier_invoice_detail + JOIN m_item + ON M_ItemID = SupplierInvoiceDetailItemID + AND SupplierInvoiceDetailSupplierInvoiceID = ? + AND SupplierInvoiceDetailIsActive = 'Y' + AND SupplierInvoiceDetailIsVerified = 'Y' + JOIN fa_class + ON Fa_ClassID = M_ItemFa_ClassID + AND Fa_ClassIsActive = 'Y'"; + $que_dp = $this->db_onedev->query($sql_dp, [$orderid]); + if (!$que_dp) { + $this->sys_error_db("failed to get coa id dp tagihans", $this->db_onedev); + exit; + } + $dataDP = $que_dp->result_array(); + $excludeIds = array_column($dataDP, 'Fa_ClassDownPaymentCoaID'); + $excludeIds[] = 563; // always excluded + $excludeIds = array_unique($excludeIds); + $excludeIds = array_values($excludeIds); // re-index + + $notInPlaceholders = implode(',', array_fill(0, count($excludeIds), '?')); + + $sql = "SELECT + SupplierInvoiceID as tagihan_id, PurchaseOrderNumber as tagihan_number, jurnalTxDescription as pasien, jurnalTxCredit as tagihan_total, @@ -135,14 +212,20 @@ class Bill extends MY_Controller jurnalTxID SupplierInvoiceDetailID, PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID FROM supplier_invoice + JOIN receive_order_po + ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID + JOIN receive_order_po_detail + ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID JOIN purchase_order - ON SupplierInvoicePurchaseOrderID = PurchaseOrderID + ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber + AND jurnalAddOnIsActive = 'Y' JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID + AND jurnalTxIsActive = 'Y' AND jurnalTxCredit <> 0 - AND jurnalTxCoaID <> 563 + AND jurnalTxCoaID NOT IN ($notInPlaceholders) LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierInvoiceIsActive = 'Y' @@ -152,7 +235,7 @@ class Bill extends MY_Controller AND SupplierPaymentDetailIsActive = 'Y' WHERE SupplierInvoiceID = ? GROUP BY jurnalTxID"; - $query = $this->db_onedev->query($sql, [$orderid]); + $query = $this->db_onedev->query($sql, array_merge($excludeIds, [$orderid])); if ($query) { $rows = $query->result_array(); return $rows; @@ -395,10 +478,19 @@ class Bill extends MY_Controller $dp_params = [$regionalid]; + // ── INSTALLMENT branch WHERE ──────────────────────────── + $inst_where = " inst.SupplierInstallmentIsActive = 'Y' + AND rop.ReceiveOrderPoS_RegionalID = ? "; + + $inst_params = [$regionalid]; + // ── UNION base ─────────────────────────────────────────── $sql_base = " SELECT si.SupplierInvoiceID, + 0 AS DownpaymentID, + 0 AS InstallmentID, + 0 AS parent_invoice_id, si.SupplierInvoiceNumber, si.SupplierInvoiceDraftPaymentDate, si.SupplierInvoiceDraftPaymentDate AS filter_date, @@ -441,7 +533,10 @@ class Bill extends MY_Controller UNION ALL SELECT - dp.SupplierDownpaymentID * -1 AS SupplierInvoiceID, + 0 AS SupplierInvoiceID, + dp.SupplierDownpaymentID AS DownpaymentID, + 0 AS InstallmentID, + 0 AS parent_invoice_id, CONCAT('DP-', po.PurchaseOrderNumber) AS SupplierInvoiceNumber, dp.SupplierDownpaymentDueDate AS SupplierInvoiceDraftPaymentDate, dp.SupplierDownpaymentDueDate AS filter_date, @@ -480,7 +575,59 @@ class Bill extends MY_Controller ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID JOIN purchase_order po ON po.PurchaseOrderID = dp.SupplierDownpaymentPurchasOrderID - WHERE $dp_where"; + WHERE $dp_where + + UNION ALL + + SELECT + 0 AS SupplierInvoiceID, + 0 AS DownpaymentID, + inst.SupplierInstallmentID AS InstallmentID, + si_inst.SupplierInvoiceID AS parent_invoice_id, + CONCAT('INST-', si_inst.SupplierInvoiceNumber) AS SupplierInvoiceNumber, + inst.SupplierInstallmentDueDate AS SupplierInvoiceDraftPaymentDate, + inst.SupplierInstallmentDueDate AS filter_date, + inst.SupplierInstallmentIsLunas AS flaglunas, + si_inst.SupplierInvoiceSupplierInvoiceNumber AS SupplierInvoiceSupplierInvoiceNumber, + DATE_FORMAT( + IFNULL(si_inst.SupplierInvoiceSupplierInvoiceDate,''),'%d-%m-%Y' + ) AS tanggalinvoice, + inst_sup.SupplierName AS SupplierName, + IFNULL(sp.SupplierPaymentID,0) AS SupplierPaymentID, + IFNULL(sp.SupplierPaymentIsConfirm,'N') AS SupplierPaymentIsConfirm, + IFNULL(sp.SupplierPaymentIsApproved,'N') AS SupplierPaymentIsApproved, + IFNULL(sp.SupplierPaymentIsVerif,'N') AS SupplierPaymentIsVerif, + IFNULL(sp.SupplierPaymentIsActive,'Y') AS SupplierPaymentIsActive, + IFNULL(sp.SupplierPaymentCashierNumber,'') AS SupplierPaymentCashierNumber, + DATE_FORMAT( + inst.SupplierInstallmentDueDate,'%d-%m-%Y' + ) AS tanggalbayar, + inst.SupplierInstallmentAmount AS totalbill, + CASE WHEN inst.SupplierInstallmentStatus = 'Paid' + THEN inst.SupplierInstallmentAmount + ELSE 0 END AS paid, + CASE WHEN inst.SupplierInstallmentStatus = 'Paid' + THEN 0 + ELSE inst.SupplierInstallmentAmount END AS unpaid, + '' AS SupplierPaymentNumber, + 0 AS SupplierPaymentAmount, + '' AS SupplierPaymentDate, + '' AS notes, + '' AS tagihans, + 0 AS xrounding, + '' AS chex, + 'INSTALLMENT' AS type + FROM supplier_installment inst + LEFT JOIN supplier_payment sp + ON sp.SupplierPaymentSupplierInstallmentID = inst.SupplierInstallmentID + AND sp.SupplierPaymentIsActive = 'Y' + JOIN supplier_invoice si_inst + ON si_inst.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID + JOIN receive_order_po rop + ON rop.ReceiveOrderPoID = si_inst.SupplierInvoiceReceiveOrderPoID + JOIN supplier inst_sup + ON inst_sup.SupplierID = inst.SupplierInstallmentSupplierID + WHERE $inst_where"; // ── Outer common filters ───────────────────────────────── $outer_where = " SupplierPaymentIsActive = 'Y' @@ -506,7 +653,7 @@ class Bill extends MY_Controller FROM ($sql_base) AS combined WHERE $outer_where"; - $count_params = array_merge($inv_params, $dp_params, $outer_params); + $count_params = array_merge($inv_params, $dp_params, $inst_params, $outer_params); $query = $this->db_onedev->query($sql_count, $count_params); $tot_count = 0; @@ -526,7 +673,7 @@ class Bill extends MY_Controller ORDER BY SupplierInvoiceID ASC LIMIT ? OFFSET ?"; - $data_params = array_merge($inv_params, $dp_params, $outer_params, [$number_limit, $number_offset]); + $data_params = array_merge($inv_params, $dp_params, $inst_params, $outer_params, [$number_limit, $number_offset]); $query = $this->db_onedev->query($sql_data, $data_params); $rows = $query->result_array(); @@ -537,7 +684,7 @@ class Bill extends MY_Controller // ── Downpayment branch ────────────────────────── if ($v['type'] === 'DP') { $rows[$k]['chex'] = false; - $dp_id = abs($v['SupplierInvoiceID']); + $dp_id = $v['DownpaymentID']; $s_payment = $this->db_onedev->query(" SELECT @@ -566,6 +713,39 @@ class Bill extends MY_Controller continue; } + // ── Installment branch ───────────────────────── + if ($v['type'] === 'INSTALLMENT') { + $rows[$k]['chex'] = false; + $inst_id = $v['InstallmentID']; + $parent_invoice_id = $v['parent_invoice_id']; + + $s_payment = $this->db_onedev->query(" + SELECT + GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber, + SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount, + GROUP_CONCAT( + DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y') + SEPARATOR ', ' + ) as SupplierPaymentDate + FROM supplier_payment + WHERE SupplierPaymentIsActive = 'Y' + AND SupplierPaymentSupplierInstallmentID = ?", + [$inst_id] + )->row(); + + $amount = $s_payment->SupplierPaymentAmount + ? $s_payment->SupplierPaymentAmount + : "0.00"; + + $rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber; + $rows[$k]['SupplierPaymentAmount'] = $amount; + $rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate; + $rows[$k]['paid'] = $amount; + $rows[$k]['notes'] = $this->add_notes_installment($inst_id); + $rows[$k]['tagihans'] = $this->add_tagihans($parent_invoice_id); + continue; + } + // ── Invoice branch ────────────────────────────── $rows[$k]['chex'] = false; $inv_id = $v['SupplierInvoiceID']; @@ -611,8 +791,8 @@ class Bill extends MY_Controller : "0.00"; $rows[$k]['unpaid'] = number_format($unpaid, 2, '.', ''); - $rows[$k]['notes'] = $this->add_notes($inv_id); - $rows[$k]['tagihans'] = $this->add_tagihans($inv_id); + $rows[$k]['notes'] = $this->add_notes($inv_id); + $rows[$k]['tagihans'] = $this->add_tagihans($inv_id); } } diff --git a/application/controllers/mockup/supplierpaymentcashierv5/PaymentV2.php b/application/controllers/mockup/supplierpaymentcashierv5/PaymentV2.php index a5ea7d5..25992dd 100644 --- a/application/controllers/mockup/supplierpaymentcashierv5/PaymentV2.php +++ b/application/controllers/mockup/supplierpaymentcashierv5/PaymentV2.php @@ -3,9 +3,10 @@ class PaymentV2 extends MY_Controller { var $db; + public function index() { - echo "API"; + echo 'API'; } public function __construct() @@ -17,8 +18,8 @@ class PaymentV2 extends MY_Controller { try { if (!$this->isLogin) { - $this->sys_error("invalid token"); - exit; + $this->sys_error('invalid token'); + exit(); } $this->db->trans_begin(); @@ -26,15 +27,15 @@ class PaymentV2 extends MY_Controller $param = $this->sys_input; $users = $this->sys_user; - # Generate number supplier payment # - $sql_gennumber = "SELECT `fn_numbering`(?) as numberx"; + // Generate number supplier payment # + $sql_gennumber = 'SELECT `fn_numbering`(?) as numberx'; $paygroupnum = $this->db->query($sql_gennumber, ['PC'])->row()->numberx; $paynumber = $this->db->query($sql_gennumber, ['PN'])->row()->numberx; if ($paygroupnum == '' || $paynumber == '') { $this->db->trans_rollback(); - $this->sys_error_db("[Error] generate number supplier payment"); - exit; + $this->sys_error_db('[Error] generate number supplier payment'); + exit(); } $rounding = 0; @@ -43,17 +44,17 @@ class PaymentV2 extends MY_Controller $rounding = round($sisa, 2); } - # UPDATE header supplier payment # + // UPDATE header supplier payment # $sql_updateheader = "UPDATE supplier_payment SET - SupplierPaymentIsConfirm = 'Y', - SupplierPaymentConfirmUserID = ?, - SupplierPaymentGroupNumber = ?, - SupplierPaymentCashierNumber = ?, - SupplierPaymentRounding = ?, - SupplierPaymentConfirmDate = now(), - SupplierPaymentNote = ?, - SupplierPaymentCoaID = ? - WHERE SupplierPaymentID = ?"; + SupplierPaymentIsConfirm = 'Y', + SupplierPaymentConfirmUserID = ?, + SupplierPaymentGroupNumber = ?, + SupplierPaymentCashierNumber = ?, + SupplierPaymentRounding = ?, + SupplierPaymentConfirmDate = now(), + SupplierPaymentNote = ?, + SupplierPaymentCoaID = ? + WHERE SupplierPaymentID = ?"; $que_updateheader = $this->db->query($sql_updateheader, [ $users['M_UserID'], $paygroupnum, @@ -61,179 +62,304 @@ class PaymentV2 extends MY_Controller $rounding, $param['keterangan'], $param['paymenttype'], - $param['orderid'] + $param['orderid'], ]); if (!$que_updateheader) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] update supplier payment header"); - exit; + $this->sys_error_db('[Error] update supplier payment header'); + exit(); } - # UPDATE status lunas supplier invoice # - if ($param['type'] == 'DP') { - $sql_updatedp = "UPDATE supplier_downpayment - SET SupplierDownpaymentIsLunas = 'Y' - WHERE SupplierDownpaymentID = ?"; - $que_updatedp = $this->db->query($sql_updatedp, [ - abs($param['SupplierInvoiceID']) - ]); - if (!$que_updatedp) { - $this->db->trans_rollback(); - $this->sys_error_db("[Error] update status lunas downpayment"); - exit; - } - } else { - $sql_suppinvoice = "UPDATE supplier_invoice - SET SupplierInvoiceIsLunas = 'Y' - WHERE SupplierInvoiceID = ?"; - $que_suppinvoice = $this->db->query($sql_suppinvoice, [$param['SupplierInvoiceID']]); - if (!$que_suppinvoice) { - $this->db->trans_rollback(); - $this->sys_error_db("[Error] update status lunas invoice"); - exit; - } + // UPDATE status lunas supplier invoice # + switch ($param['type']) { + case 'DP': + $sql_updatedp = "UPDATE supplier_downpayment + SET SupplierDownpaymentIsLunas = 'Y' + WHERE SupplierDownpaymentID = ?"; + $que_updatedp = $this->db->query($sql_updatedp, [ + abs($param['DownpaymentID']), + ]); + if (!$que_updatedp) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] update status lunas downpayment'); + exit(); + } + break; + case 'INSTALLMENT': + $sql_updinstlment = "UPDATE supplier_installment + SET SupplierInstallmentIsLunas = 'Y' + WHERE SupplierInstallmentID = ?"; + $que_updinstlment = $this->db->query($sql_updinstlment, [ + $param['InstallmentID'], + ]); + if (!$que_updinstlment) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] update status lunas installment'); + exit(); + } + + $sql_updKontrak = "UPDATE purchase_order_asset_contract c + JOIN supplier_installment inst + ON inst.SupplierInstallmentPurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID + SET + c.PurchaseOrderAssetContractInstallmentPaid = c.PurchaseOrderAssetContractInstallmentPaid + 1, + c.PurchaseOrderAssetContractStatus = IF( + c.PurchaseOrderAssetContractInstallmentPaid + 1 >= c.PurchaseOrderAssetContractInstallmentNumber, + 'lunas', + 'belum lunas' + ), + c.PurchaseOrderAssetContractLastUpdated = NOW() + WHERE inst.SupplierInstallmentID = ? + AND inst.SupplierInstallmentIsActive = 'Y' + AND c.PurchaseOrderAssetContractIsActive = 'Y'"; + $que_updKontrak = $this->db->query($sql_updKontrak, [ + $param['InstallmentID'], + ]); + if (!$que_updKontrak) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] update kontrak cicilan'); + exit(); + } + break; + default: + $sql_suppinvoice = "UPDATE supplier_invoice + SET SupplierInvoiceIsLunas = 'Y' + WHERE SupplierInvoiceID = ?"; + $que_suppinvoice = $this->db->query($sql_suppinvoice, [ + $param['SupplierInvoiceID'], + ]); + if (!$que_suppinvoice) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] update status lunas invoice'); + exit(); + } + break; } - # GET Latest data supplier payment # - $sql_suppayment = "SELECT * FROM supplier_payment WHERE SupplierPaymentID = ?"; + // GET Latest data supplier payment for logging # + $sql_suppayment = 'SELECT * FROM supplier_payment WHERE SupplierPaymentID = ?'; $que_suppayment = $this->db->query($sql_suppayment, [$param['orderid']]); if (!$que_suppayment) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data latest supplier payment"); - exit; + $this->sys_error_db('[Error] get data latest supplier payment'); + exit(); } $suppayment_header = $que_suppayment->row_array(); $suppayment_detail = []; - if ($param['type'] == 'DP') { - $sql_suppaymentdetail = "SELECT supplier_downpayment.* - FROM supplier_payment - JOIN supplier_downpayment - ON SupplierPaymentSupplierDownpaymentID = SupplierDownpaymentID - AND SupplierDownpaymentIsActive = 'Y' - WHERE SupplierPaymentID = ?"; - $que_suppaymentdetail = $this->db->query($sql_suppaymentdetail, [$param['orderid']]); - if (!$que_suppaymentdetail) { - $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data latest supplier downpayment"); - exit; - } - $suppayment_detail = $que_suppaymentdetail->result_array(); - } else { - $sql_suppaymentdetail = "SELECT * FROM supplier_payment_detail - WHERE SupplierPaymentDetailSupplierPaymentID = ?"; - $que_suppaymentdetail = $this->db->query($sql_suppaymentdetail, [$param['orderid']]); - if (!$que_suppaymentdetail) { - $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data latest supplier payment detail"); - exit; - } - $suppayment_detail = $que_suppaymentdetail->result_array(); + switch ($param['type']) { + case 'DP': + $sql_suppaymentdetail = "SELECT supplier_downpayment.* + FROM supplier_payment + JOIN supplier_downpayment + ON SupplierPaymentSupplierDownpaymentID = SupplierDownpaymentID + AND SupplierDownpaymentIsActive = 'Y' + WHERE SupplierPaymentID = ?"; + $que_suppaymentdetail = $this->db->query($sql_suppaymentdetail, [$param['orderid']]); + if (!$que_suppaymentdetail) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] get data latest supplier downpayment'); + exit(); + } + $suppayment_detail = $que_suppaymentdetail->result_array(); + break; + case 'INSTALLMENT': + $sql_suppaymentdetail = "SELECT + supplier_installment.*, + PurchaseOrderAssetContractInstallmentNumber AS qtyPay, + PurchaseOrderAssetContractInstallmentPaid AS qtyPaid + FROM supplier_payment + JOIN supplier_installment + ON SupplierInstallmentID = SupplierPaymentSupplierInstallmentID + AND SupplierInstallmentIsActive = 'Y' + JOIN purchase_order_asset_contract + ON PurchaseOrderAssetContractPurchaseOrderID = SupplierInstallmentPurchaseOrderID + AND PurchaseOrderAssetContractIsActive = 'Y' + WHERE SupplierPaymentID = ?"; + $que_suppaymentdetail = $this->db->query($sql_suppaymentdetail, [$param['orderid']]); + if (!$que_suppaymentdetail) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] get data latest supplier installment'); + exit(); + } + $suppayment_detail = $que_suppaymentdetail->result_array(); + break; + default: + $sql_suppaymentdetail = 'SELECT * FROM supplier_payment_detail + WHERE SupplierPaymentDetailSupplierPaymentID = ?'; + $que_suppaymentdetail = $this->db->query($sql_suppaymentdetail, [$param['orderid']]); + if (!$que_suppaymentdetail) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] get data latest supplier payment detail'); + exit(); + } + $suppayment_detail = $que_suppaymentdetail->result_array(); + break; } $data_log = [ - "header" => $suppayment_header, - "detail" => $suppayment_detail + 'header' => $suppayment_header, + 'detail' => $suppayment_detail, ]; - # LOG activity confirm payment # + // LOG activity confirm payment # $messg = "Pembayaran Faktur No: {$suppayment_header['SupplierPaymentNumber']}"; $messg .= " telah dikonfirmasi oleh {$users['M_UserUsername']} dengan nomor"; $messg .= " pembayaran kasir: {$suppayment_header['SupplierPaymentCashierNumber']}"; - $this->insert_activity_log( - "PF", - "CONFIRM", - $messg, - $param['orderid'], - $data_log, - $users['M_UserID'] - ); + $this->insert_activity_log('PF', 'CONFIRM', $messg, $param['orderid'], $data_log, $users['M_UserID']); - # INSERT JURNAL # + // INSERT JURNAL # $detail_transac = []; - - if ($param['type'] == "DP") { - $sql_coaDP = "SELECT - coaID, - coaDescription, - SupplierDownpaymentAmount, - M_ItemID, - SupplierPaymentNumber, - M_ItemID - FROM supplier_payment - JOIN supplier_downpayment - ON SupplierDownpaymentID = SupplierPaymentSupplierDownpaymentID - AND SupplierDownpaymentIsActive = 'Y' - JOIN purchase_order_detail - ON SupplierDownpaymentPurchasOrderID = PurchaseOrderDetailPurchaseOrderID - AND PurchaseOrderDetailIsActive = 'Y' - JOIN m_item - ON M_ItemID = PurchaseOrderDetailItemID - AND M_ItemIsActive = 'Y' - JOIN fa_class - ON Fa_ClassID = M_ItemFa_ClassID - AND M_ItemIsActive = 'Y' - JOIN coa - ON coaID = Fa_ClassDownPaymentCoaID - AND coaIsActive = 'Y' - WHERE SupplierPaymentID = ?"; - $que_coaDP = $this->db->query($sql_coaDP, [ - $param['orderid'] - ]); - if (!$que_coaDP) { - $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data hutang item"); - exit; - } - $data_dp = $que_coaDP->result_array(); - foreach ($data_dp as $key => $dp) { - $detail_transac[] = [ - "coaID" => $dp['coaID'], - "coaDescription" => $dp['coaDescription'], - "debit" => $dp['SupplierDownpaymentAmount'], - "credit" => 0, - "addoncode" => "DP-JFA", - "addonvalue" => $dp['SupplierPaymentNumber'], - "addonitemid" => $dp['M_ItemID'] - ]; - } - } else { - # GET data hutang # - $sql_datahutang = "SELECT - SupplierPaymentNumber AS addonvalue, - SupplierPaymentDetailID, - jurnalTxCoaID AS coaID, - jurnalTxDescription AS coaDescription, - SupplierPaymentDetailAmount, - SupplierInvoiceDetailItemID - FROM supplier_payment - JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID - JOIN supplier_invoice_detail ON SupplierInvoiceDetailSupplierInvoiceID = SupplierPaymentSupplierInvoiceID - AND SupplierInvoiceDetailIsActive = 'Y' - JOIN jurnal_tx ON SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID - WHERE SupplierPaymentID = ? - AND SupplierPaymentDetailIsActive = 'Y'"; - $que_datahutang = $this->db->query($sql_datahutang, [$param['orderid']]); - if (!$que_datahutang) { - $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data hutang item"); - exit; - } - $data_hutang = $que_datahutang->result_array(); - foreach ($data_hutang as $key => $debt) { - $detail_transac[] = [ - "coaID" => $debt['coaID'], - "coaDescription" => $debt['coaDescription'], - "debit" => $debt['SupplierPaymentDetailAmount'], - "credit" => 0, - "addoncode" => "JFA", - "addonvalue" => $debt['addonvalue'], - "addonitemid" => $debt['SupplierInvoiceDetailItemID'] - ]; - } + switch ($param['type']) { + case 'DP': + $sql_coaDP = "SELECT + coaID, + coaDescription, + SupplierDownpaymentAmount, + M_ItemID, + SupplierPaymentNumber, + M_ItemID + FROM supplier_payment + JOIN supplier_downpayment + ON SupplierDownpaymentID = SupplierPaymentSupplierDownpaymentID + AND SupplierDownpaymentIsActive = 'Y' + JOIN purchase_order_detail + ON SupplierDownpaymentPurchasOrderID = PurchaseOrderDetailPurchaseOrderID + AND PurchaseOrderDetailIsActive = 'Y' + JOIN m_item + ON M_ItemID = PurchaseOrderDetailItemID + AND M_ItemIsActive = 'Y' + JOIN fa_class + ON Fa_ClassID = M_ItemFa_ClassID + AND M_ItemIsActive = 'Y' + JOIN coa + ON coaID = Fa_ClassDownPaymentCoaID + AND coaIsActive = 'Y' + WHERE SupplierPaymentID = ?"; + $que_coaDP = $this->db->query($sql_coaDP, [ + $param['orderid'], + ]); + if (!$que_coaDP) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] get data hutang item dp'); + exit(); + } + $data_dp = $que_coaDP->result_array(); + if (empty($data_dp)) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] no COA found for uang muka item'); + exit(); + } + foreach ($data_dp as $key => $dp) { + $detail_transac[] = [ + 'coaID' => $dp['coaID'], + 'coaDescription' => $dp['coaDescription'], + 'debit' => $dp['SupplierDownpaymentAmount'], + 'credit' => 0, + 'addoncode' => 'DP-JFA', + 'addonvalue' => $dp['SupplierPaymentNumber'], + 'addonitemid' => $dp['M_ItemID'], + ]; + } + break; + case 'INSTALLMENT': + $sql_datahutang = "SELECT + coaID, + coaDescription, + SupplierInstallmentAmount, + M_ItemID, + SupplierPaymentNumber, + M_ItemID + FROM supplier_payment + JOIN supplier_installment + ON SupplierInstallmentID = SupplierPaymentSupplierInstallmentID + AND SupplierInstallmentIsActive = 'Y' + JOIN purchase_order_detail + ON SupplierInstallmentPurchaseOrderID = PurchaseOrderDetailPurchaseOrderID + AND PurchaseOrderDetailIsActive = 'Y' + JOIN m_item + ON M_ItemID = PurchaseOrderDetailItemID + AND M_ItemIsActive = 'Y' + JOIN fa_class + ON Fa_ClassID = M_ItemFa_ClassID + AND M_ItemIsActive = 'Y' + JOIN coa + ON coaID = Fa_ClassHutangCoaID + AND coaIsActive = 'Y' + WHERE SupplierPaymentID = ?"; + $que_datahutang = $this->db->query($sql_datahutang, [ + $param['orderid'], + ]); + if (!$que_datahutang) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] get data hutang item cicilan'); + exit(); + } + $data_cicil = $que_datahutang->result_array(); + if (empty($data_cicil)) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] no COA found for installment item'); + exit(); + } + foreach ($data_cicil as $key => $cicil) { + $detail_transac[] = [ + 'coaID' => $cicil['coaID'], + 'coaDescription' => $cicil['coaDescription'], + 'debit' => $cicil['SupplierInstallmentAmount'], + 'credit' => 0, + 'addoncode' => 'INST-JFA', + 'addonvalue' => $cicil['SupplierPaymentNumber'], + 'addonitemid' => $cicil['M_ItemID'], + ]; + } + break; + default: + // GET data hutang # + $sql_datahutang = "SELECT + SupplierPaymentNumber AS addonvalue, + SupplierPaymentDetailID, + jurnalTxCoaID AS coaID, + jurnalTxDescription AS coaDescription, + SupplierPaymentDetailAmount, + SupplierInvoiceDetailItemID + FROM supplier_payment + JOIN supplier_payment_detail + ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID + JOIN supplier_invoice_detail + ON SupplierInvoiceDetailSupplierInvoiceID = SupplierPaymentSupplierInvoiceID + AND SupplierInvoiceDetailIsActive = 'Y' + JOIN jurnal_tx + ON SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID + AND jurnalTxIsActive = 'Y' + WHERE SupplierPaymentID = ? + AND SupplierPaymentDetailIsActive = 'Y'"; + $que_datahutang = $this->db->query($sql_datahutang, [$param['orderid']]); + if (!$que_datahutang) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] get data hutang item'); + exit(); + } + $data_hutang = $que_datahutang->result_array(); + if (empty($data_hutang)) { + $this->db->trans_rollback(); + $this->sys_error_db('[Error] no COA found for hutang item'); + exit(); + } + foreach ($data_hutang as $key => $debt) { + $detail_transac[] = [ + 'coaID' => $debt['coaID'], + 'coaDescription' => $debt['coaDescription'], + 'debit' => $debt['SupplierPaymentDetailAmount'], + 'credit' => 0, + 'addoncode' => 'JFA', + 'addonvalue' => $debt['addonvalue'], + 'addonitemid' => $debt['SupplierInvoiceDetailItemID'], + ]; + } + break; } - # GET data bayar # + // GET data bayar # $sql_databayar = "SELECT CONCAT('Jurnal Payment Invoice Nomor : ', SupplierPaymentNumber, DATE_FORMAT(now(), @@ -257,68 +383,86 @@ class PaymentV2 extends MY_Controller $que_databayar = $this->db->query($sql_databayar, [$param['orderid']]); if (!$que_databayar) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data bayar"); - exit; + $this->sys_error_db('[Error] get data bayar'); + exit(); } $data_bayar = $que_databayar->row_array(); $detail_transac[] = [ - "coaID" => $data_bayar['coaID'], - "coaDescription" => $data_bayar['coaDescription'], - "debit" => 0, - "credit" => abs($data_bayar['bayar']), - "addoncode" => "PAYINVSG", - "addonvalue" => $data_bayar['addonvalue'], - "addonitemid" => 0 + 'coaID' => $data_bayar['coaID'], + 'coaDescription' => $data_bayar['coaDescription'], + 'debit' => 0, + 'credit' => abs($data_bayar['bayar']), + 'addoncode' => 'PAYINVSG', + 'addonvalue' => $data_bayar['addonvalue'], + 'addonitemid' => 0, ]; - # rugi / untung dari rounding # + // rugi / untung dari rounding # $sql_lossprofit = "SELECT coaID, coaDescription FROM coa WHERE coaAccountNo = ? AND coaIsActive = 'Y'"; $data_round = doubleval($data_bayar['rounding']); if ($data_round > 0) { - # loss # + // loss # $que_lossprofit = $this->db->query($sql_lossprofit, ['6120402001']); if (!$que_lossprofit) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data coa loss sisa kas"); - exit; + $this->sys_error_db('[Error] get data coa loss sisa kas'); + exit(); } $loss_coa = $que_lossprofit->row_array(); $detail_transac[] = [ - "coaID" => $loss_coa['coaID'], - "coaDescription" => $loss_coa['coaDescription'], - "debit" => abs($data_round), - "credit" => 0, - "addoncode" => "PAYINVSG", - "addonvalue" => $data_bayar['addonvalue'], - "addonitemid" => 0 + 'coaID' => $loss_coa['coaID'], + 'coaDescription' => $loss_coa['coaDescription'], + 'debit' => abs($data_round), + 'credit' => 0, + 'addoncode' => 'PAYINVSG', + 'addonvalue' => $data_bayar['addonvalue'], + 'addonitemid' => 0, ]; } elseif ($data_round < 0) { - # profit # + // profit # $que_lossprofit = $this->db->query($sql_lossprofit, ['6110500001']); if (!$que_lossprofit) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data coa profit sisa kas"); - exit; + $this->sys_error_db('[Error] get data coa profit sisa kas'); + exit(); } $profit_coa = $que_lossprofit->row_array(); $detail_transac[] = [ - "coaID" => $profit_coa['coaID'], - "coaDescription" => $profit_coa['coaDescription'], - "debit" => 0, - "credit" => abs($data_round), - "addoncode" => "PAYINVSG", - "addonvalue" => $data_bayar['addonvalue'], - "addonitemid" => 0 + 'coaID' => $profit_coa['coaID'], + 'coaDescription' => $profit_coa['coaDescription'], + 'debit' => 0, + 'credit' => abs($data_round), + 'addoncode' => 'PAYINVSG', + 'addonvalue' => $data_bayar['addonvalue'], + 'addonitemid' => 0, ]; } + // "PI Cicilan Aset - {$invoiceNumber}"; + $description = ''; + // "Jurnal cicilan ke-{$cicilanKe} dari {$totalCicilan} | {$namaKontrak} | PO: {$nomorPO} | Periode {$periode}"; + + switch ($param['type']) { + case 'DP': + $data_bayar['jurnaltitle'] .= " | Pembayaran Uang Muka Aset - {$param['dpkode']}"; + break; + case 'INSTALLMENT': + $cicil = $suppayment_detail[0]; + $data_bayar['jurnaltitle'] .= " | Pembayaran Cicilan Aset - {$param['installmentkode']}"; + $data_bayar['jurnaldesc'] .= " | Jurnal cicilan ke-{$cicil['qtyPaid']} dari {$cicil['qtyPay']}"; + break; + default: + // code + break; + } + $this->insertJurnal($users, $data_bayar, $detail_transac); $this->db->trans_commit(); - $this->sys_ok("success update v2 test"); + $this->sys_ok('success update v2 test'); } catch (Exception $exc) { $message = $exc->getMessage(); $this->sys_error($message); @@ -329,22 +473,22 @@ class PaymentV2 extends MY_Controller { try { if (!$this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + $this->sys_error('Invalid Token'); + exit(); } $this->db->trans_begin(); $param = $this->sys_input; $users = $this->sys_user; - # Generate number supplier payment # - $sql_gennumber = "SELECT `fn_numbering`(?) as numberx"; + // Generate number supplier payment # + $sql_gennumber = 'SELECT `fn_numbering`(?) as numberx'; $paygroupnum = $this->db->query($sql_gennumber, ['PC'])->row()->numberx; if ($paygroupnum == '') { $this->db->trans_rollback(); - $this->sys_error_db("[Error] generate number group supplier payment"); - exit; + $this->sys_error_db('[Error] generate number group supplier payment'); + exit(); } $rounding = 0; @@ -353,27 +497,26 @@ class PaymentV2 extends MY_Controller $rounding = round($sisa, 2); } - $lastIndex = count($param['details']) - 1; - # LOOP details invoice payment # + // LOOP details invoice payment # foreach ($param['details'] as $idx => $obj) { $paynumber = $this->db->query($sql_gennumber, ['PN'])->row()->numberx; if ($paynumber == '') { $this->db->trans_rollback(); - $this->sys_error_db("[Error] generate number kasir supplier payment"); - exit; + $this->sys_error_db('[Error] generate number kasir supplier payment'); + exit(); } $SupplierPaymentID = $obj['SupplierPaymentID']; $SupplierInvoiceID = $obj['SupplierInvoiceID']; - # CEK index invoice terakhir # + // CEK index invoice terakhir # $roundvalue = 0; if ($idx == $lastIndex) { $roundvalue = $rounding; } - # UPDATE header supplier payment # + // UPDATE header supplier payment # $sql_updateheader = "UPDATE supplier_payment SET SupplierPaymentIsConfirm = 'Y', SupplierPaymentConfirmUserID = ?, @@ -391,67 +534,60 @@ class PaymentV2 extends MY_Controller $roundvalue, $param['keterangan'], $param['paymenttype'], - $SupplierPaymentID + $SupplierPaymentID, ]); if (!$que_updateheader) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] update supplier payment header"); - exit; + $this->sys_error_db('[Error] update supplier payment header'); + exit(); } - # UPDATE status lunas supplier invoice # + // UPDATE status lunas supplier invoice # $sql_suppinvoice = "UPDATE supplier_invoice SET SupplierInvoiceIsLunas = 'Y' WHERE SupplierInvoiceID = ?"; $que_suppinvoice = $this->db->query($sql_suppinvoice, [$SupplierInvoiceID]); if (!$que_suppinvoice) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] update status lunas invoice"); - exit; + $this->sys_error_db('[Error] update status lunas invoice'); + exit(); } - # GET Latest data supplier payment # - $sql_suppayment = "SELECT * FROM supplier_payment WHERE SupplierPaymentID = ?"; + // GET Latest data supplier payment # + $sql_suppayment = 'SELECT * FROM supplier_payment WHERE SupplierPaymentID = ?'; $que_suppayment = $this->db->query($sql_suppayment, [$SupplierPaymentID]); if (!$que_suppayment) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data latest supplier payment"); - exit; + $this->sys_error_db('[Error] get data latest supplier payment'); + exit(); } $suppayment_header = $que_suppayment->row_array(); - $sql_suppaymentdetail = "SELECT * FROM supplier_payment_detail - WHERE SupplierPaymentDetailSupplierPaymentID = ?"; + $sql_suppaymentdetail = 'SELECT * FROM supplier_payment_detail + WHERE SupplierPaymentDetailSupplierPaymentID = ?'; $que_suppaymentdetail = $this->db->query($sql_suppaymentdetail, [$SupplierPaymentID]); if (!$que_suppaymentdetail) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data latest supplier payment detail"); - exit; + $this->sys_error_db('[Error] get data latest supplier payment detail'); + exit(); } $suppayment_detail = $que_suppaymentdetail->result_array(); $data_log = [ - "header" => $suppayment_header, - "detail" => $suppayment_detail + 'header' => $suppayment_header, + 'detail' => $suppayment_detail, ]; - # LOG activity confirm payment # + // LOG activity confirm payment # $messg = "Pembayaran Faktur No: {$suppayment_header['SupplierPaymentNumber']}"; $messg .= " telah dikonfirmasi oleh {$users['M_UserUsername']} dengan nomor"; $messg .= " pembayaran kasir: {$suppayment_header['SupplierPaymentCashierNumber']}"; - $this->insert_activity_log( - "PF", - "CONFIRM", - $messg, - $SupplierPaymentID, - $data_log, - $users['M_UserID'] - ); + $this->insert_activity_log('PF', 'CONFIRM', $messg, $SupplierPaymentID, $data_log, $users['M_UserID']); - ## INSERT jurnal ## + // # INSERT jurnal ## $detail_transac = []; - # GET data hutang # + // GET data hutang # $sql_datahutang = "SELECT SupplierPaymentNumber AS addonvalue, SupplierPaymentDetailID, @@ -469,23 +605,23 @@ class PaymentV2 extends MY_Controller $que_datahutang = $this->db->query($sql_datahutang, [$SupplierPaymentID]); if (!$que_datahutang) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data hutang item"); - exit; + $this->sys_error_db('[Error] get data hutang item'); + exit(); } $data_hutang = $que_datahutang->result_array(); foreach ($data_hutang as $key => $debt) { $detail_transac[] = [ - "coaID" => $debt['coaID'], - "coaDescription" => $debt['coaDescription'], - "debit" => $debt['SupplierPaymentDetailAmount'], - "credit" => 0, - "addoncode" => "JFA", - "addonvalue" => $debt['addonvalue'], - "addonitemid" => $debt['SupplierInvoiceDetailItemID'] + 'coaID' => $debt['coaID'], + 'coaDescription' => $debt['coaDescription'], + 'debit' => $debt['SupplierPaymentDetailAmount'], + 'credit' => 0, + 'addoncode' => 'JFA', + 'addonvalue' => $debt['addonvalue'], + 'addonitemid' => $debt['SupplierInvoiceDetailItemID'], ]; } - # GET data bayar # + // GET data bayar # $sql_databayar = "SELECT CONCAT('Jurnal Payment Invoice Nomor : ', SupplierPaymentNumber, DATE_FORMAT(now(), @@ -509,61 +645,61 @@ class PaymentV2 extends MY_Controller $que_databayar = $this->db->query($sql_databayar, [$SupplierPaymentID]); if (!$que_databayar) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data bayar"); - exit; + $this->sys_error_db('[Error] get data bayar'); + exit(); } $data_bayar = $que_databayar->row_array(); $detail_transac[] = [ - "coaID" => $data_bayar['coaID'], - "coaDescription" => $data_bayar['coaDescription'], - "debit" => 0, - "credit" => abs($data_bayar['bayar']), - "addoncode" => "PAYINVGR", - "addonvalue" => $data_bayar['addonvalue'], - "addonitemid" => 0 + 'coaID' => $data_bayar['coaID'], + 'coaDescription' => $data_bayar['coaDescription'], + 'debit' => 0, + 'credit' => abs($data_bayar['bayar']), + 'addoncode' => 'PAYINVGR', + 'addonvalue' => $data_bayar['addonvalue'], + 'addonitemid' => 0, ]; - # rugi / untung dari rounding # + // rugi / untung dari rounding # $sql_lossprofit = "SELECT coaID, coaDescription FROM coa WHERE coaAccountNo = ? AND coaIsActive = 'Y'"; $data_round = doubleval($data_bayar['rounding']); if ($data_round > 0) { - # loss # + // loss # $que_lossprofit = $this->db->query($sql_lossprofit, ['6120402001']); if (!$que_lossprofit) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data coa loss sisa kas"); - exit; + $this->sys_error_db('[Error] get data coa loss sisa kas'); + exit(); } $loss_coa = $que_lossprofit->row_array(); $detail_transac[] = [ - "coaID" => $loss_coa['coaID'], - "coaDescription" => $loss_coa['coaDescription'], - "debit" => abs($data_round), - "credit" => 0, - "addoncode" => "PAYINVGR", - "addonvalue" => $data_bayar['addonvalue'], - "addonitemid" => 0 + 'coaID' => $loss_coa['coaID'], + 'coaDescription' => $loss_coa['coaDescription'], + 'debit' => abs($data_round), + 'credit' => 0, + 'addoncode' => 'PAYINVGR', + 'addonvalue' => $data_bayar['addonvalue'], + 'addonitemid' => 0, ]; } elseif ($data_round < 0) { - # profit # + // profit # $que_lossprofit = $this->db->query($sql_lossprofit, ['6110500001']); if (!$que_lossprofit) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get data coa profit sisa kas"); - exit; + $this->sys_error_db('[Error] get data coa profit sisa kas'); + exit(); } $profit_coa = $que_lossprofit->row_array(); $detail_transac[] = [ - "coaID" => $profit_coa['coaID'], - "coaDescription" => $profit_coa['coaDescription'], - "debit" => 0, - "credit" => abs($data_round), - "addoncode" => "PAYINVGR", - "addonvalue" => $data_bayar['addonvalue'], - "addonitemid" => 0 + 'coaID' => $profit_coa['coaID'], + 'coaDescription' => $profit_coa['coaDescription'], + 'debit' => 0, + 'credit' => abs($data_round), + 'addoncode' => 'PAYINVGR', + 'addonvalue' => $data_bayar['addonvalue'], + 'addonitemid' => 0, ]; } @@ -571,7 +707,7 @@ class PaymentV2 extends MY_Controller } $this->db->trans_commit(); - $this->sys_ok("[Success] success multi payment invoice"); + $this->sys_ok('[Success] success multi payment invoice'); } catch (Exception $exc) { $message = $exc->getMessage(); $this->sys_error($message); @@ -580,49 +716,49 @@ class PaymentV2 extends MY_Controller private function insertJurnal($users, $databayar, $detailtrx) { - # GET periode jurnal # + // GET periode jurnal # $sql_periode = "SELECT periodeID FROM periode WHERE DATE(NOW()) BETWEEN periodeStartDate AND periodeEndDate AND periodeIsActive = 'Y' AND periodeIsClosed = 'N'"; $que_periode = $this->db->query($sql_periode, []); if (!$que_periode) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] find periode id"); - exit; + $this->sys_error_db('[Error] find periode id'); + exit(); } if ($que_periode->num_rows() === 0) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] Waktu periode tidak ditemukan"); - exit; + $this->sys_error_db('[Error] Waktu periode tidak ditemukan'); + exit(); } $JurnalPeriode = $que_periode->row_array()['periodeID']; - # GENERATE nomor jurnal # + // GENERATE nomor jurnal # $sql_jurnalno = "SELECT `fn_numbering`('J') AS jnumber"; $que_jurnalno = $this->db->query($sql_jurnalno, []); if (!$que_jurnalno) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] generate jurnal number"); - exit; + $this->sys_error_db('[Error] generate jurnal number'); + exit(); } $JurnalNumber = $que_jurnalno->row_array()['jnumber']; $JurnalTitle = $databayar['jurnaltitle']; $JurnalDescp = $databayar['jurnaldesc']; - # GET jurnal type # + // GET jurnal type # $sql_jurnaltype = "SELECT JurnalTypeID FROM jurnal_type WHERE JurnalTypeCode = 'PAYMENTINV' AND JurnalTypeIsActive = 'Y'"; $que_jurnaltype = $this->db->query($sql_jurnaltype, []); if (!$que_jurnaltype) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] get jurnal type"); - exit; + $this->sys_error_db('[Error] get jurnal type'); + exit(); } $JurnalType = $que_jurnaltype->row_array()['JurnalTypeID']; - # INSERT jurnal header # - $sql_insheader = "INSERT INTO jurnal ( + // INSERT jurnal header # + $sql_insheader = 'INSERT INTO jurnal ( jurnalM_BranchCompanyID, JurnalS_RegionalID, jurnalM_BranchCode, @@ -633,7 +769,7 @@ class PaymentV2 extends MY_Controller jurnalDate, jurnalJurnalTypeID, jurnalM_UserID - ) VALUES (?,?,?,?,?,?,?,NOW(),?,?)"; + ) VALUES (?,?,?,?,?,?,?,NOW(),?,?)'; $que_inserjurnal = $this->db->query($sql_insheader, [ $users['M_BranchCompanyID'], $users['S_RegionalID'], @@ -643,42 +779,42 @@ class PaymentV2 extends MY_Controller $JurnalTitle, $JurnalDescp, $JurnalType, - $users['M_UserID'] + $users['M_UserID'], ]); if (!$que_inserjurnal) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] insert jurnal header"); - exit; + $this->sys_error_db('[Error] insert jurnal header'); + exit(); } $JurnalID = $this->db->insert_id(); - # INSERT jurnal tx # + // INSERT jurnal tx # foreach ($detailtrx as $key => $trax) { - $sql_trax = "INSERT INTO jurnal_tx ( + $sql_trax = 'INSERT INTO jurnal_tx ( jurnalTxJurnalID, jurnalTxCoaID, jurnalTxDescription, jurnalTxDebit, jurnalTxCredit, jurnalTxM_UserID - ) VALUES (?,?,?,?,?,?)"; + ) VALUES (?,?,?,?,?,?)'; $que_trax = $this->db->query($sql_trax, [ $JurnalID, $trax['coaID'], $trax['coaDescription'], $trax['debit'], $trax['credit'], - $users['M_UserID'] + $users['M_UserID'], ]); if (!$que_trax) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] insert jurnal tx"); - exit; + $this->sys_error_db('[Error] insert jurnal tx'); + exit(); } $JurnalTxID = $this->db->insert_id(); - # INSERT jurnal addon # - $sql_addon = "INSERT INTO jurnal_addon ( + // INSERT jurnal addon # + $sql_addon = 'INSERT INTO jurnal_addon ( jurnalAddOnJurnalID, jurnalAddOnJurnalTxID, jurnalAddOnCode, @@ -686,19 +822,19 @@ class PaymentV2 extends MY_Controller jurnalAddOnM_ItemID, jurnalAddOnCreated, jurnalAddOnCreatedUserID - ) VALUES (?,?,?,?,?,NOW(),?)"; + ) VALUES (?,?,?,?,?,NOW(),?)'; $que_addon = $this->db->query($sql_addon, [ $JurnalID, $JurnalTxID, $trax['addoncode'], $trax['addonvalue'], $trax['addonitemid'], - $users['M_UserID'] + $users['M_UserID'], ]); if (!$que_addon) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] insert jurnal addon"); - exit; + $this->sys_error_db('[Error] insert jurnal addon'); + exit(); } } } @@ -708,11 +844,11 @@ class PaymentV2 extends MY_Controller $json = json_encode($data); if (json_last_error() !== JSON_ERROR_NONE) { $this->db->trans_rollback(); - $this->sys_error("[Error] encode data into json for log activity"); - exit; + $this->sys_error('[Error] encode data into json for log activity'); + exit(); } - $sql = "INSERT INTO user_activity( + $sql = 'INSERT INTO user_activity( UserActivityCode, UserActivityStatus, UserActivityDescription, @@ -720,19 +856,19 @@ class PaymentV2 extends MY_Controller UserActivityData, UserActivityUserID, UserActivityCreated - ) VALUES (?,?,?,?,?,?,NOW())"; + ) VALUES (?,?,?,?,?,?,NOW())'; $que = $this->db->query($sql, [ $actcode, $status, $desc, $refID, $json, - $userID + $userID, ]); if (!$que) { $this->db->trans_rollback(); - $this->sys_error_db("[Error] insert into table log activity"); - exit; + $this->sys_error_db('[Error] insert into table log activity'); + exit(); } } } diff --git a/application/controllers/mockup/supplierpaymentv4/Bill.php b/application/controllers/mockup/supplierpaymentv4/Bill.php index 48905a8..1e482d0 100644 --- a/application/controllers/mockup/supplierpaymentv4/Bill.php +++ b/application/controllers/mockup/supplierpaymentv4/Bill.php @@ -114,38 +114,126 @@ class Bill extends MY_Controller } } + public function add_notes_installment($orderid) + { + $sql = "SELECT SupplierPaymentSupplierInstallmentID as note_order_id, + SupplierPaymentID as note_id, + SupplierInstallmentID as detail_id, + SupplierPaymentDate as note_date, + SupplierPaymentNumber as note_number, + GROUP_CONCAT(DISTINCT coaDescription separator ' , ') as paymenttypes_name, + SUM(SupplierInstallmentAmount) as note_amount, + n.M_UserUsername as note_user, + SupplierInstallmentIsActive as note_active, + 'N' as show_detail, + SupplierPaymentNote as keterangan, + SupplierPaymentCoaID, + coaID, + coaDescription, + SupplierPaymentIsConfirm, + CONCAT( + 'Confirmed by : ',c.M_UserUsername, ' ', + DATE_FORMAT(SupplierPaymentConfirmDate,'%d-%m-%Y %H:%i') + ) AS d_confirm, + SupplierPaymentIsApproved, + CONCAT( + 'Approved by : ',a.M_UserUsername, ' ', + DATE_FORMAT(SupplierPaymentApprovedDate,'%d-%m-%Y %H:%i') + ) AS d_approved, + CONCAT( + 'Verified by : ',b.M_UserUsername, ' ', + DATE_FORMAT(SupplierPaymentVerifDate,'%d-%m-%Y %H:%i') + ) AS d_verif + FROM supplier_payment + JOIN supplier_installment + ON SupplierInstallmentID = SupplierPaymentSupplierInstallmentID + AND SupplierInstallmentIsActive = 'Y' + LEFT JOIN coa ON SupplierPaymentCoaID = coaID + LEFT JOIN m_user n ON SupplierPaymentUserID = n.M_UserID + LEFT JOIN m_user c ON SupplierPaymentConfirmUserID = c.M_UserID + LEFT JOIN m_user a ON SupplierPaymentApprovedUserID = a.M_UserID + LEFT JOIN m_user b ON SupplierPaymentVerifUserID = b.M_UserID + WHERE SupplierPaymentSupplierInstallmentID = {$orderid} + AND SupplierPaymentIsActive = 'Y' + GROUP BY SupplierPaymentID"; + $query = $this->db_onedev->query($sql); + if ($query) { + $rows = $query->result_array(); + return $rows ?: []; + } else { + $this->sys_error_db("get Installment notes", $this->db_onedev); + exit; + } + } + public function add_tagihans($orderid) { - $sql = "SELECT SupplierInvoiceID as tagihan_id, - PurchaseOrderNumber as tagihan_number, - jurnalTxDescription as pasien, - jurnalTxCredit as tagihan_total, - IF(SupplierPaymentDetailID IS NULL , jurnalTxCredit, jurnalTxCredit - SUM(SupplierPaymentDetailAmount)) as tagihan_tagihan, - 0 as tagihan_bayar, - DATE_FORMAT(SupplierInvoiceDueDate,'%d-%m-%Y') as tagihan_duedate, - SupplierInvoiceIsActive as tagihan_active, - 'N' as show_detail, - jurnalTxID SupplierInvoiceDetailID, - PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID + $sql_dp = "SELECT + Fa_ClassDownPaymentCoaID + FROM supplier_invoice_detail + JOIN m_item + ON M_ItemID = SupplierInvoiceDetailItemID + AND SupplierInvoiceDetailSupplierInvoiceID = ? + AND SupplierInvoiceDetailIsActive = 'Y' + AND SupplierInvoiceDetailIsVerified = 'Y' + JOIN fa_class + ON Fa_ClassID = M_ItemFa_ClassID + AND Fa_ClassIsActive = 'Y'"; + $que_dp = $this->db_onedev->query($sql_dp, [$orderid]); + if (!$que_dp) { + $this->sys_error_db("failed to get coa id dp tagihans", $this->db_onedev); + exit; + } + $dataDP = $que_dp->result_array(); + $excludeIds = array_column($dataDP, 'Fa_ClassDownPaymentCoaID'); + $excludeIds[] = 563; // always excluded + $excludeIds = array_unique($excludeIds); + $excludeIds = array_values($excludeIds); // re-index - FROM supplier_invoice - JOIN receive_order_po ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID - JOIN receive_order_po_detail ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID - JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID - JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber - JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID AND jurnalTxCredit <> 0 AND jurnalTxCoaID <> 563 - LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierInvoiceIsActive = 'Y' - LEFT JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID AND SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID AND SupplierPaymentDetailIsActive = 'Y' - WHERE - SupplierInvoiceID = {$orderid} - GROUP BY jurnalTxID - "; - $query = $this->db_onedev->query($sql); + $notInPlaceholders = implode(',', array_fill(0, count($excludeIds), '?')); + + $sql = "SELECT + SupplierInvoiceID as tagihan_id, + PurchaseOrderNumber as tagihan_number, + jurnalTxDescription as pasien, + jurnalTxCredit as tagihan_total, + IF(SupplierPaymentDetailID IS NULL , jurnalTxCredit, jurnalTxCredit - SUM(SupplierPaymentDetailAmount)) as tagihan_tagihan, + 0 as tagihan_bayar, + DATE_FORMAT(SupplierInvoiceDueDate,'%d-%m-%Y') as tagihan_duedate, + SupplierInvoiceIsActive as tagihan_active, + 'N' as show_detail, + jurnalTxID SupplierInvoiceDetailID, + PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID + FROM supplier_invoice + JOIN receive_order_po + ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID + JOIN receive_order_po_detail + ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID + JOIN purchase_order + ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID + JOIN jurnal_addon + ON jurnalAddOnValue = SupplierInvoiceNumber + AND jurnalAddOnIsActive = 'Y' + JOIN jurnal_tx + ON jurnalTxJurnalID = jurnalAddOnJurnalID + AND jurnalTxIsActive = 'Y' + AND jurnalTxCredit <> 0 + AND jurnalTxCoaID NOT IN ($notInPlaceholders) + LEFT JOIN supplier_payment + ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID + AND SupplierInvoiceIsActive = 'Y' + LEFT JOIN supplier_payment_detail + ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID + AND SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID + AND SupplierPaymentDetailIsActive = 'Y' + WHERE SupplierInvoiceID = ? + GROUP BY jurnalTxID"; + $query = $this->db_onedev->query($sql, array_merge($excludeIds, [$orderid])); if ($query) { $rows = $query->result_array(); return $rows; } else { - $this->sys_error_db("get notes", $this->db_onedev); + $this->sys_error_db("get tagihans", $this->db_onedev); exit; } } @@ -371,7 +459,24 @@ class Bill extends MY_Controller $enddate, ]; - // ── COUNT query — UNION of both sources ──────────────────── + // ── INSTALLMENT WHERE ─────────────────────────────────── + $inst_where = " inst.SupplierInstallmentIsActive = 'Y' + AND IF(sp.SupplierPaymentID IS NULL,'N','Y') = ? + AND CONCAT('INST-', si.SupplierInvoiceNumber) LIKE ? + AND sup.SupplierName LIKE ? + AND rop.ReceiveOrderPoS_RegionalID = ? + AND inst.SupplierInstallmentDueDate BETWEEN ? AND ? "; + + $inst_params = [ + $status, + '%' . $search . '%', + '%' . $supplier . '%', + $regionalid, + $startdate, + $enddate, + ]; + + // ── COUNT query — UNION of all three sources ──────────── $sql_count = "SELECT SUM(cnt) as total FROM ( SELECT count(*) as cnt FROM supplier_invoice @@ -390,9 +495,24 @@ class Bill extends MY_Controller JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID WHERE $dp_where + + UNION ALL + + SELECT count(*) as cnt + FROM supplier_installment inst + LEFT JOIN supplier_payment sp + ON sp.SupplierPaymentSupplierInstallmentID = inst.SupplierInstallmentID + AND sp.SupplierPaymentIsActive = 'Y' + JOIN supplier_invoice si + ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID + JOIN receive_order_po rop + ON rop.ReceiveOrderPoID = si.SupplierInvoiceReceiveOrderPoID + JOIN supplier sup + ON sup.SupplierID = inst.SupplierInstallmentSupplierID + WHERE $inst_where ) AS combined"; - $count_params = array_merge($inv_params, $dp_params); + $count_params = array_merge($inv_params, $dp_params, $inst_params); $query = $this->db_onedev->query($sql_count, $count_params); $tot_count = 0; @@ -410,6 +530,8 @@ class Bill extends MY_Controller SELECT * FROM ( SELECT SupplierInvoiceID, + 0 as DownpaymentID, + 0 as InstallmentID, SupplierInvoiceNumber, SupplierInvoiceDraftPaymentDate, SupplierInvoiceIsLunas as flaglunas, @@ -426,6 +548,7 @@ class Bill extends MY_Controller '' as SupplierPaymentDate, '' as notes, '' as tagihans, + 0 as parent_invoice_id, 'INVOICE' as type FROM supplier_invoice LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID @@ -440,14 +563,16 @@ class Bill extends MY_Controller UNION ALL SELECT - SupplierDownpaymentID * -1 as SupplierInvoiceID, + 0 as SupplierInvoiceID, + SupplierDownpaymentID as DownpaymentID, + 0 as InstallmentID, CONCAT('DP-', PurchaseOrderNumber) as SupplierInvoiceNumber, SupplierDownpaymentDueDate as SupplierInvoiceDraftPaymentDate, SupplierDownpaymentIsLunas as flaglunas, SupplierName, DATE_FORMAT(SupplierDownpaymentDueDate,'%d-%m-%Y') as tanggalbayar, - 'N' as SupplierPaymentIsApproved, - '' as SupplierPaymentCashierNumber, + IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved, + IFNULL(SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber, SupplierDownpaymentAmount as totalbill, CASE WHEN SupplierDownpaymentStatus = 'Paid' THEN SupplierDownpaymentAmount @@ -461,17 +586,65 @@ class Bill extends MY_Controller '' as SupplierPaymentDate, '' as notes, '' as tagihans, + 0 as parent_invoice_id, 'DP' as type FROM supplier_downpayment JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID + LEFT JOIN supplier_payment + ON SupplierPaymentSupplierDownpaymentID = SupplierDownpaymentID + AND SupplierPaymentIsActive = 'Y' WHERE $dp_where + + UNION ALL + + SELECT + 0 as SupplierInvoiceID, + 0 as DownpaymentID, + inst.SupplierInstallmentID as InstallmentID, + CONCAT('INST-', si.SupplierInvoiceNumber) as SupplierInvoiceNumber, + inst.SupplierInstallmentDueDate as SupplierInvoiceDraftPaymentDate, + inst.SupplierInstallmentIsLunas as flaglunas, + sup.SupplierName, + DATE_FORMAT(inst.SupplierInstallmentDueDate,'%d-%m-%Y') as tanggalbayar, + IFNULL(sp.SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved, + IFNULL(sp.SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber, + inst.SupplierInstallmentAmount as totalbill, + CASE WHEN inst.SupplierInstallmentStatus = 'Paid' + THEN inst.SupplierInstallmentAmount + ELSE 0 END as paid, + CASE WHEN inst.SupplierInstallmentStatus = 'Paid' + THEN 0 + ELSE inst.SupplierInstallmentAmount END as unpaid, + 0 as SupplierPaymentID, + '' as SupplierPaymentNumber, + 0 as SupplierPaymentAmount, + '' as SupplierPaymentDate, + '' as notes, + '' as tagihans, + si.SupplierInvoiceID as parent_invoice_id, + 'INSTALLMENT' as type + FROM supplier_installment inst + LEFT JOIN supplier_payment sp + ON sp.SupplierPaymentSupplierInstallmentID = inst.SupplierInstallmentID + AND sp.SupplierPaymentIsActive = 'Y' + JOIN supplier_invoice si + ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID + JOIN receive_order_po rop + ON rop.ReceiveOrderPoID = si.SupplierInvoiceReceiveOrderPoID + JOIN supplier sup + ON sup.SupplierID = inst.SupplierInstallmentSupplierID + WHERE $inst_where ) AS combined ORDER BY SupplierInvoiceID ASC LIMIT ? OFFSET ?"; - $data_params = array_merge($inv_params, $dp_params, [$number_limit, $number_offset]); + $data_params = array_merge($inv_params, $dp_params, $inst_params, [$number_limit, $number_offset]); $query = $this->db_onedev->query($sql_data, $data_params); + if (!$query) { + $this->sys_error_db("payment instructions data", $this->db_onedev); + exit; + } $rows = $query->result_array(); // ── ENRICH — per-row sub-queries ─────────────────────────── @@ -480,7 +653,7 @@ class Bill extends MY_Controller // ── Downpayment branch ────────────────────────── if ($v['type'] === 'DP') { - $dp_id = abs($v['SupplierInvoiceID']); + $dp_id = $v['DownpaymentID']; $s_payment = $this->db_onedev->query(" SELECT @@ -515,6 +688,44 @@ class Bill extends MY_Controller continue; } + // ── Installment branch ───────────────────────── + if ($v['type'] === 'INSTALLMENT') { + $inst_id = $v['InstallmentID']; + $parent_invoice_id = $v['parent_invoice_id']; + + $s_payment = $this->db_onedev->query(" + SELECT + GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber, + SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount, + IFNULL(SupplierPaymentID,0) as SupplierPaymentID, + GROUP_CONCAT( + DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y') + SEPARATOR ', ' + ) as SupplierPaymentDate + FROM supplier_payment + WHERE SupplierPaymentIsActive = 'Y' + AND SupplierPaymentSupplierInstallmentID = ?", + [$inst_id] + )->row(); + + $amount = $s_payment->SupplierPaymentAmount + ? $s_payment->SupplierPaymentAmount + : "0.00"; + $rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID + ? $s_payment->SupplierPaymentID + : '0'; + $rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber + ? $s_payment->SupplierPaymentNumber + : ''; + $rows[$k]['SupplierPaymentAmount'] = $amount; + $rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate; + $rows[$k]['paid'] = $amount; + $rows[$k]['notes'] = $this->add_notes_installment($inst_id); + $rows[$k]['tagihans'] = $this->add_tagihans($parent_invoice_id); + // totalbill, unpaid already correct from UNION CASE + continue; + } + // ── Invoice branch ─────────────────────────────── $inv_id = $v['SupplierInvoiceID']; diff --git a/application/controllers/mockup/supplierpaymentv4/Payment.php b/application/controllers/mockup/supplierpaymentv4/Payment.php index d406719..a487fe8 100644 --- a/application/controllers/mockup/supplierpaymentv4/Payment.php +++ b/application/controllers/mockup/supplierpaymentv4/Payment.php @@ -3,23 +3,24 @@ class Payment extends MY_Controller { var $db_smartone; + public function index() { - echo "API"; + echo 'API'; } public function __construct() { parent::__construct(); - $this->db_onedev = $this->load->database("onedev", true); + $this->db_onedev = $this->load->database('onedev', true); } function lookup_type() { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } $query = "SELECT coaID as id, coaCode as code, @@ -41,8 +42,8 @@ class Payment extends MY_Controller FROM m_paymenttype WHERE coaIsActive = 'Y'"; $que = $this->db_onedev->query($query); if (!$que) { - $this->sys_error_db("failed to query tipe"); - exit; + $this->sys_error_db('failed to query tipe'); + exit(); } $rows = $que->result_array(); foreach ($rows as $k => $v) { @@ -55,21 +56,20 @@ class Payment extends MY_Controller $rows[$k]['chex'] = true; } $result = array( - "total" => count($rows), - "records" => $rows, + 'total' => count($rows), + 'records' => $rows, ); $this->sys_ok($result); - exit; + exit(); } function selectpaymenttypeold() { - try { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } $rows = []; $query = "SELECT * FROM m_paymenttype @@ -78,10 +78,9 @@ class Payment extends MY_Controller //echo $query; $rows['paymenttypes'] = $this->db_onedev->query($query)->result_array(); - $result = array( - "total" => count($rows), - "records" => $rows, + 'total' => count($rows), + 'records' => $rows, ); $this->sys_ok($result); } catch (Exception $exc) { @@ -92,17 +91,16 @@ class Payment extends MY_Controller function selectpaymenttype() { - try { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } $rows = []; $regionalid = $this->sys_user['S_RegionalID']; $prm = $this->sys_input; - $search = $prm["search"]; + $search = $prm['search']; $query = "SELECT coaID, coaAccountNo, coaDescription, @@ -134,10 +132,9 @@ ORDER BY coaAccountNo ASC"; //echo $query; $rows['paymenttypes'] = $this->db_onedev->query($query)->result_array(); - $result = array( - "total" => count($rows), - "records" => $rows, + 'total' => count($rows), + 'records' => $rows, ); $this->sys_ok($result); } catch (Exception $exc) { @@ -148,12 +145,11 @@ ORDER BY coaAccountNo ASC"; function selectbank() { - try { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } $rows = []; $query = " SELECT * @@ -165,15 +161,14 @@ ORDER BY coaAccountNo ASC"; //echo $query; $que = $this->db_onedev->query($query); if (!$que) { - $this->sys_error_db("failed"); - exit; + $this->sys_error_db('failed'); + exit(); } $rows['banks'] = $que->result_array(); - $result = array( - "total" => count($rows), - "records" => $rows, + 'total' => count($rows), + 'records' => $rows, ); $this->sys_ok($result); } catch (Exception $exc) { @@ -184,12 +179,11 @@ ORDER BY coaAccountNo ASC"; function selectaccount() { - try { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } $rows = []; $query = " SELECT M_BankAccountID as M_BankAccountID, CONCAT(Nat_BankCode,' (',M_BankAccountNo,')') as M_BankAccountName @@ -201,15 +195,14 @@ ORDER BY coaAccountNo ASC"; //echo $query; $que = $this->db_onedev->query($query); if (!$que) { - $this->sys_error_db("failed"); - exit; + $this->sys_error_db('failed'); + exit(); } $rows['accounts'] = $que->result_array(); - $result = array( - "total" => count($rows), - "records" => $rows, + 'total' => count($rows), + 'records' => $rows, ); $this->sys_ok($result); } catch (Exception $exc) { @@ -221,9 +214,9 @@ ORDER BY coaAccountNo ASC"; function lookup_banks() { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } $query = "SELECT Nat_BankID as id, Nat_BankCode as name FROM nat_bank @@ -232,25 +225,25 @@ ORDER BY coaAccountNo ASC"; ORDER BY Nat_BankCode DESC"; $que = $this->db_onedev->query($query); if (!$que) { - $this->sys_error_db("failed to query tipe"); - exit; + $this->sys_error_db('failed to query tipe'); + exit(); } $rows = $que->result_array(); $result = array( - "total" => count($rows), - "records" => $rows, + 'total' => count($rows), + 'records' => $rows, ); $this->sys_ok($result); - exit; + exit(); } function lookup_accounts() { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } $query = "SELECT M_BankAccountID as id, CONCAT(Nat_BankCode,' (',M_BankAccountNo,')') as name FROM m_bank_account @@ -260,23 +253,23 @@ ORDER BY coaAccountNo ASC"; ORDER BY Nat_BankCode DESC"; $que = $this->db_onedev->query($query); if (!$que) { - $this->sys_error_db("failed to query tipe"); - exit; + $this->sys_error_db('failed to query tipe'); + exit(); } $rows = $que->result_array(); $result = array( - "total" => count($rows), - "records" => $rows, + 'total' => count($rows), + 'records' => $rows, ); $this->sys_ok($result); } function searchcard() { - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } $prm = $this->sys_input; @@ -284,7 +277,7 @@ ORDER BY coaAccountNo ASC"; $tot_count = 0; $q = [ - 'search' => '%' + 'search' => '%', ]; if ($prm['search'] != '') { @@ -313,10 +306,10 @@ ORDER BY coaAccountNo ASC"; $query = $this->db_onedev->query($sql, $q['search']); //echo $query; if ($query) { - $tot_count = $query->result_array()[0]["total"]; + $tot_count = $query->result_array()[0]['total']; } else { - $this->sys_error_db("m_city count", $this->db_onedev); - exit; + $this->sys_error_db('m_city count', $this->db_onedev); + exit(); } if ($prm['search'] != '') { $sql = " @@ -342,20 +335,20 @@ ORDER BY coaAccountNo ASC"; if ($query) { $rows = $query->result_array(); //echo $this->db_onedev->last_query(); - $result = array("total" => $tot_count, "records" => $rows, "total_display" => sizeof($rows)); + $result = array('total' => $tot_count, 'records' => $rows, 'total_display' => sizeof($rows)); $this->sys_ok($result); } else { - $this->sys_error_db("m_city rows", $this->db_onedev); - exit; + $this->sys_error_db('m_city rows', $this->db_onedev); + exit(); } } function pay() { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } //# ambil parameter input @@ -364,20 +357,17 @@ ORDER BY coaAccountNo ASC"; $orderid = $prm['orderid']; $payments = $prm['payments']; //$xnumber = $this->db_onedev->query("SELECT `fn_numbering`('PAY') as numberx")->row()->numberx; - $sql = "INSERT INTO supplier_payment + $sql = 'INSERT INTO supplier_payment (SupplierPaymentSupplierInvoiceID,SupplierPaymentDate,SupplierPaymentCreated,SupplierPaymentUserID) - VALUES (?,CURDATE(),NOW(),?)"; - $query = $this->db_onedev->query( - $sql, - array( - $orderid, - $xuserid - ) - ); + VALUES (?,CURDATE(),NOW(),?)'; + $query = $this->db_onedev->query($sql, array( + $orderid, + $xuserid, + )); if (!$query) { - $this->sys_error_db("supplier_payment insert"); - exit; + $this->sys_error_db('supplier_payment insert'); + exit(); } $headerid = $this->db_onedev->insert_id(); //echo $headerid; @@ -396,12 +386,25 @@ ORDER BY coaAccountNo ASC"; $amount = $actual; } - $sql = "CALL `sp_bill_payment_add_cash`(" . $orderid . "," . $amount . "," . $amount . "," . $headerid . "," . $v['id'] . "," . $xuserid . ")"; + $sql = + 'CALL `sp_bill_payment_add_cash`(' + . $orderid + . ',' + . $amount + . ',' + . $amount + . ',' + . $headerid + . ',' + . $v['id'] + . ',' + . $xuserid + . ')'; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_payment_detail cash insert"); - exit; + $this->sys_error_db('supplier_payment_detail cash insert'); + exit(); } } else { if (intval($v['leftvalue']) > 0) { @@ -416,14 +419,33 @@ ORDER BY coaAccountNo ASC"; $selected_edc = $v['selected_edc']['id']; $selected_account = $v['selected_account']['id']; } - $sql = "CALL `sp_bill_payment_add_noncash`(" . $orderid . "," . $amount . "," . $amount . "," . $headerid . "," . $v['id'] . "," . $xuserid . "," . $selected_card . "," . $selected_edc . "," . $selected_account . ")"; + $sql = + 'CALL `sp_bill_payment_add_noncash`(' + . $orderid + . ',' + . $amount + . ',' + . $amount + . ',' + . $headerid + . ',' + . $v['id'] + . ',' + . $xuserid + . ',' + . $selected_card + . ',' + . $selected_edc + . ',' + . $selected_account + . ')'; //echo $sql; $query = $this->db_onedev->query($sql); //echo $this->db_onedev->last_query(); if (!$query) { - $this->sys_error_db("supplier_payment_detail non cash insert"); - exit; + $this->sys_error_db('supplier_payment_detail non cash insert'); + exit(); } } } @@ -453,120 +475,23 @@ ORDER BY coaAccountNo ASC"; else $rows[$k]['chex'] = true; } - $xdata = $this->db_onedev->query("SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}")->row(); - $result = array( - "total" => count($rows), - "records" => array('types' => $rows, 'data' => $xdata) - ); - $this->sys_ok($result); - exit; - } - - function payDownpayment() - { - if (!$this->isLogin) { - $this->sys_error("Invalid Token"); - exit; - } - - $xuserid = $this->sys_user['M_UserID']; - $prm = $this->sys_input; - $supllierDPID = abs($prm['orderid']); // SupplierDownpaymentID sent as orderid - - $this->db_onedev->trans_begin(); - - $xnumber = $this->db_onedev->query( - "SELECT `fn_numbering`('PINV') as numberx" - )->row()->numberx; - - // Insert payment header (SupplierInvoiceID = 0, linked via Downpayment FK) - $sql = "INSERT INTO supplier_payment ( - SupplierPaymentSupplierInvoiceID, - SupplierPaymentSupplierDownpaymentID, - SupplierPaymentNumber, - SupplierPaymentDate, - SupplierPaymentAmount, - SupplierPaymentCoaID, - SupplierPaymentNote, - SupplierPaymentCreated, - SupplierPaymentUserID - ) VALUES (0, ?, ?, CURDATE(), ?, ?, ?, NOW(), ?)"; - $que = $this->db_onedev->query($sql, [ - $supllierDPID, - $xnumber, - $prm['amount'], - $prm['paymenttype'], - $prm['keterangan'], - $xuserid - ]); - if (!$que) { - $this->db_onedev->trans_rollback(); - $this->sys_error_db("supplier_payment insert for DP"); - exit; - } - $headerid = $this->db_onedev->insert_id(); - - // Mark downpayment as paid - $sql_dp = "UPDATE supplier_downpayment SET - SupplierDownpaymentDueDate = ?, - SupplierDownpaymentStatus = 'Paid', - SupplierDownpaymentDate = CURDATE(), - SupplierDownpaymentLastUpdatedUserID = ? - WHERE SupplierDownpaymentID = ? - AND SupplierDownpaymentIsActive = 'Y' - AND SupplierDownpaymentStatus != 'Paid'"; - $que_dp = $this->db_onedev->query($sql_dp, [ - $prm['tanggalbayar'], - $xuserid, - $supllierDPID - ]); - if (!$que_dp) { - $this->db_onedev->trans_rollback(); - $this->sys_error_db("supplier_downpayment update status"); - exit; - } - - // Audit - $sql_audit = "SELECT * FROM supplier_payment - JOIN m_user ON M_UserID = SupplierPaymentUserID - WHERE SupplierPaymentID = ?"; - $que_audit = $this->db_onedev->query($sql_audit, [$headerid]); - $row = $que_audit->row_array(); - $data = array("header" => $row, "details" => []); - - $message = "Nomor Pembayaran DP: " . $row["SupplierPaymentNumber"] - . " berhasil dibuat oleh " . $row["M_UserUsername"]; - $this->insert_act_log( - "PF", - "NEW", - $message, - $headerid, - $this->safeJsonEncode($data), - $xuserid - ); - - $this->db_onedev->trans_commit(); - $xdata = $this->db_onedev->query( - "SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx - FROM supplier_payment WHERE SupplierPaymentID = ?", - [$headerid] + "SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}" )->row(); - $result = array( - "total" => 1, - "records" => array('data' => $xdata) + 'total' => count($rows), + 'records' => array('types' => $rows, 'data' => $xdata), ); $this->sys_ok($result); - exit; + exit(); } function paymanual() { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } //# ambil parameter input @@ -583,7 +508,7 @@ ORDER BY coaAccountNo ASC"; $keterangan = $prm['keterangan']; $bills = $prm['bills']; $xnumber = $this->db_onedev->query("SELECT `fn_numbering`('PINV') as numberx")->row()->numberx; - $sql = "INSERT INTO supplier_payment + $sql = 'INSERT INTO supplier_payment (SupplierPaymentSupplierInvoiceID, SupplierPaymentNumber, SupplierPaymentDate, @@ -592,22 +517,19 @@ ORDER BY coaAccountNo ASC"; SupplierPaymentNote, SupplierPaymentCreated, SupplierPaymentUserID) - VALUES (?,?,CURDATE(),?,?,?,NOW(),?)"; - $query = $this->db_onedev->query( - $sql, - array( - $orderid, - $xnumber, - $amount, - $paymenttype, - $keterangan, - $xuserid - ) - ); + VALUES (?,?,CURDATE(),?,?,?,NOW(),?)'; + $query = $this->db_onedev->query($sql, array( + $orderid, + $xnumber, + $amount, + $paymenttype, + $keterangan, + $xuserid, + )); $headerid = $this->db_onedev->insert_id(); if (!$query) { - $this->sys_error_db("supplier_payment insert"); - exit; + $this->sys_error_db('supplier_payment insert'); + exit(); } else { $sqlbill = "UPDATE supplier_invoice SET SupplierInvoiceDraftPaymentDate = '{$tanggalbayar}' @@ -615,11 +537,9 @@ ORDER BY coaAccountNo ASC"; $querybill = $this->db_onedev->query($sqlbill); //echo $this->db_onedev->last_query(); - } //echo $headerid; - foreach ($bills as $k => $v) { if ($v['tagihan_bayar'] > 0) { $SupplierInvoiceDetailID = $v['SupplierInvoiceDetailID']; @@ -642,100 +562,286 @@ ORDER BY coaAccountNo ASC"; $query = $this->db_onedev->query($sql); $billpaymentdetailid = $this->db_onedev->insert_id(); if (!$query) { - $this->sys_error_db("supplier_payment_detail cash insert"); - exit; + $this->sys_error_db('supplier_payment_detail cash insert'); + exit(); } else { $sqlbilldetail = "UPDATE supplier_invoice_detail SET - SupplierInvoiceDetailUnpaid = SupplierInvoiceDetailUnpaid - $tagihan_bayar - WHERE SupplierInvoiceDetailID = $SupplierInvoiceDetailID"; + SupplierInvoiceDetailUnpaid = SupplierInvoiceDetailUnpaid - $tagihan_bayar + WHERE SupplierInvoiceDetailID = $SupplierInvoiceDetailID"; $querybilldetail = $this->db_onedev->query($sqlbilldetail); - /* $sqlpayment = "INSERT INTO f_payment - (F_PaymentPurchaseOrderID, - F_PaymentDate, - F_PaymentTotal, - F_PaymentCreated, - F_PaymentLastUpdated, - F_PaymentM_UserID) - VALUES( - $SupplierInvoiceDetailPurchaseOrderID, - now(), - $tagihan_bayar, - now(), - now(), - $xuserid)"; - $querypayment = $this->db_onedev->query($sqlpayment); - $paymentid = $this->db_onedev->insert_id(); - $sqlpaymentdetail = "INSERT INTO f_paymentdetail - (F_PaymentDetailF_PaymentID, - F_PaymentDetailcoaID, - F_PaymentDetailAmount, - F_PaymentDetailActual, - F_PaymentDetailChange, - F_PaymentDetailEDCNat_BankID, - F_PaymentDetailCardNat_BankID, - F_PaymentDetailM_BankAccountID, - F_PaymentDetailCreated, - F_PaymentDetailLastUpdated, - F_PaymentDetailUserID) - VALUES( - $paymentid, - $paymenttype, - $tagihan_bayar, - $tagihan_bayar, - 0, - $edc, - $card, - $account, - now(), - now(), - $xuserid)"; - //echo $sqlpaymentdetail; - $querypaymentdetail = $this->db_onedev->query($sqlpaymentdetail); - - $sqleditbillpaymentdetail = "UPDATE supplier_payment_detail SET - SupplierPaymentDetailF_PaymentID = $paymentid - WHERE SupplierPaymentDetailID = $billpaymentdetailid"; - $queryeditbillpaymentdetail = $this->db_onedev->query($sqleditbillpaymentdetail); - - */ + /* + * $sqlpayment = "INSERT INTO f_payment + * (F_PaymentPurchaseOrderID, + * F_PaymentDate, + * F_PaymentTotal, + * F_PaymentCreated, + * F_PaymentLastUpdated, + * F_PaymentM_UserID) + * VALUES( + * $SupplierInvoiceDetailPurchaseOrderID, + * now(), + * $tagihan_bayar, + * now(), + * now(), + * $xuserid)"; + * $querypayment = $this->db_onedev->query($sqlpayment); + * $paymentid = $this->db_onedev->insert_id(); + * $sqlpaymentdetail = "INSERT INTO f_paymentdetail + * (F_PaymentDetailF_PaymentID, + * F_PaymentDetailcoaID, + * F_PaymentDetailAmount, + * F_PaymentDetailActual, + * F_PaymentDetailChange, + * F_PaymentDetailEDCNat_BankID, + * F_PaymentDetailCardNat_BankID, + * F_PaymentDetailM_BankAccountID, + * F_PaymentDetailCreated, + * F_PaymentDetailLastUpdated, + * F_PaymentDetailUserID) + * VALUES( + * $paymentid, + * $paymenttype, + * $tagihan_bayar, + * $tagihan_bayar, + * 0, + * $edc, + * $card, + * $account, + * now(), + * now(), + * $xuserid)"; + * //echo $sqlpaymentdetail; + * $querypaymentdetail = $this->db_onedev->query($sqlpaymentdetail); + * + * $sqleditbillpaymentdetail = "UPDATE supplier_payment_detail SET + * SupplierPaymentDetailF_PaymentID = $paymentid + * WHERE SupplierPaymentDetailID = $billpaymentdetailid"; + * $queryeditbillpaymentdetail = $this->db_onedev->query($sqleditbillpaymentdetail); + * + */ } } } - $sql = "SELECT * FROM supplier_payment + $sql = 'SELECT * FROM supplier_payment JOIN m_user ON M_UserID = SupplierPaymentUserID - WHERE SupplierPaymentID = ?"; + WHERE SupplierPaymentID = ?'; $query = $this->db_onedev->query($sql, [$headerid]); $row = $query->row_array(); - $sql = "SELECT * FROM supplier_payment_detail - WHERE SupplierPaymentDetailSupplierPaymentID = ?"; + $sql = 'SELECT * FROM supplier_payment_detail + WHERE SupplierPaymentDetailSupplierPaymentID = ?'; $query = $this->db_onedev->query($sql, [$headerid]); $rows = $query->row_array(); $data = array( - "header" => $row, - "details" => $rows + 'header' => $row, + 'details' => $rows, ); - $message = "Nomor Pembayaran Faktur: " . $row["SupplierPaymentNumber"] . " berhasil dibuat oleh " . $row["M_UserUsername"]; - $this->insert_act_log("PF", "NEW", $message, $headerid, $this->safeJsonEncode($data), $xuserid); + $message = + 'Nomor Pembayaran Faktur: ' + . $row['SupplierPaymentNumber'] + . ' berhasil dibuat oleh ' + . $row['M_UserUsername']; + $this->insert_act_log('PF', 'NEW', $message, $headerid, $this->safeJsonEncode($data), $xuserid); - $xdata = $this->db_onedev->query("SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}")->row(); + $xdata = $this->db_onedev->query( + "SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}" + )->row(); $result = array( - "total" => count($rows), - "records" => array('data' => $xdata) + 'total' => count($rows), + 'records' => array('data' => $xdata), ); $this->sys_ok($result); - exit; + exit(); + } + + function payDownpayment() + { + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); + } + + $xuserid = $this->sys_user['M_UserID']; + $prm = $this->sys_input; + $supllierDPID = abs($prm['orderid']); // SupplierDownpaymentID sent as orderid + + $this->db_onedev->trans_begin(); + + $xnumber = $this->db_onedev->query("SELECT `fn_numbering`('PINV') as numberx")->row()->numberx; + + // Insert payment header (SupplierInvoiceID = 0, linked via Downpayment FK) + $sql = 'INSERT INTO supplier_payment ( + SupplierPaymentSupplierInvoiceID, + SupplierPaymentSupplierDownpaymentID, + SupplierPaymentNumber, + SupplierPaymentDate, + SupplierPaymentAmount, + SupplierPaymentCoaID, + SupplierPaymentNote, + SupplierPaymentCreated, + SupplierPaymentUserID + ) VALUES (0, ?, ?, CURDATE(), ?, ?, ?, NOW(), ?)'; + $que = $this->db_onedev->query($sql, [ + $supllierDPID, + $xnumber, + $prm['amount'], + $prm['paymenttype'], + $prm['keterangan'], + $xuserid, + ]); + if (!$que) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('supplier_payment insert for DP'); + exit(); + } + $headerid = $this->db_onedev->insert_id(); + + // Mark downpayment as paid + $sql_dp = "UPDATE supplier_downpayment SET + SupplierDownpaymentDueDate = ?, + SupplierDownpaymentStatus = 'Paid', + SupplierDownpaymentDate = CURDATE(), + SupplierDownpaymentLastUpdatedUserID = ? + WHERE SupplierDownpaymentID = ? + AND SupplierDownpaymentIsActive = 'Y' + AND SupplierDownpaymentStatus != 'Paid'"; + $que_dp = $this->db_onedev->query($sql_dp, [ + $prm['tanggalbayar'], + $xuserid, + $supllierDPID, + ]); + if (!$que_dp) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('supplier_downpayment update status'); + exit(); + } + + // Audit + $sql_audit = 'SELECT * FROM supplier_payment + JOIN m_user ON M_UserID = SupplierPaymentUserID + WHERE SupplierPaymentID = ?'; + $que_audit = $this->db_onedev->query($sql_audit, [$headerid]); + $row = $que_audit->row_array(); + $data = array('header' => $row, 'details' => []); + + $message = + 'Nomor Pembayaran DP: ' . $row['SupplierPaymentNumber'] . ' berhasil dibuat oleh ' . $row['M_UserUsername']; + $this->insert_act_log('PF', 'NEW', $message, $headerid, $this->safeJsonEncode($data), $xuserid); + + $this->db_onedev->trans_commit(); + + $xdata = $this->db_onedev->query( + 'SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx + FROM supplier_payment WHERE SupplierPaymentID = ?', + [$headerid] + )->row(); + + $result = array( + 'total' => 1, + 'records' => array('data' => $xdata), + ); + $this->sys_ok($result); + exit(); + } + + function payInstallment() + { + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); + } + + $xuserid = $this->sys_user['M_UserID']; + $prm = $this->sys_input; + $installmentID = abs($prm['orderid']); // installmentID sent as orderid + + $this->db_onedev->trans_begin(); + + $xnumber = $this->db_onedev->query("SELECT `fn_numbering`('PINV') as numberx")->row()->numberx; + + $sql_inst = 'INSERT INTO supplier_payment ( + SupplierPaymentSupplierInvoiceID, + SupplierPaymentSupplierInstallmentID, + SupplierPaymentNumber, + SupplierPaymentDate, + SupplierPaymentAmount, + SupplierPaymentCoaID, + SupplierPaymentNote, + SupplierPaymentCreated, + SupplierPaymentUserID + ) VALUES (0, ?, ?, CURDATE(), ?, ?, ?, NOW(), ?)'; + $que_inst = $this->db_onedev->query($sql_inst, [ + $installmentID, + $xnumber, + $prm['amount'], + $prm['paymenttype'], + $prm['keterangan'], + $xuserid, + ]); + if (!$que_inst) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('supplier_payment insert for installment'); + exit(); + } + $headerid = $this->db_onedev->insert_id(); + + $sql_inst = "UPDATE supplier_installment SET + SupplierInstallmentDueDate = ?, + SupplierInstallmentStatus = 'Paid', + SupplierInstallmentLastUpdated = NOW(), + SupplierInstallmentLastUpdatedUserID = ? + WHERE SupplierInstallmentID = ? + AND SupplierInstallmentIsActive = 'Y' + AND SupplierInstallmentStatus != 'Paid'"; + $que_inst = $this->db_onedev->query($sql_inst, [ + $prm['tanggalbayar'], + $xuserid, + $installmentID, + ]); + if (!$que_inst) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('supplier_downpayment update status'); + exit(); + } + + // Audit + $sql_audit = 'SELECT * FROM supplier_payment + JOIN m_user ON M_UserID = SupplierPaymentUserID + WHERE SupplierPaymentID = ?'; + $que_audit = $this->db_onedev->query($sql_audit, [$headerid]); + $row = $que_audit->row_array(); + $data = array('header' => $row, 'details' => []); + + $message = + 'Nomor Pembayaran DP: ' . $row['SupplierPaymentNumber'] . ' berhasil dibuat oleh ' . $row['M_UserUsername']; + $this->insert_act_log('PF', 'NEW', $message, $headerid, $this->safeJsonEncode($data), $xuserid); + + $this->db_onedev->trans_commit(); + + $xdata = $this->db_onedev->query( + 'SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx + FROM supplier_payment WHERE SupplierPaymentID = ?', + [$headerid] + )->row(); + + $result = array( + 'total' => 1, + 'records' => array('data' => $xdata), + ); + + $this->sys_ok($result); + exit(); } function editpaymanual() { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } //# ambil parameter input @@ -744,49 +850,95 @@ ORDER BY coaAccountNo ASC"; $orderid = $prm['orderid']; $headerid = $prm['headerid']; $tanggalbayar = date('Y-m-d', strtotime($prm['tanggalbayar'])); - $sqlbill = "UPDATE supplier_invoice SET + $type = $prm['type']; + + $this->db_onedev->trans_begin(); + + if ($type == 'DP') { + $sqlbill = "UPDATE supplier_downpayment SET + SupplierDownpaymentDueDate = '{$tanggalbayar}' + WHERE SupplierDownpaymentID = $orderid"; + $querybill = $this->db_onedev->query($sqlbill); + if (!$querybill) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('update tanggal bayar downpayment'); + exit(); + } + } elseif ($type == 'INSTALLMENT') { + $sqlbill = "UPDATE supplier_installment SET + SupplierInstallmentDueDate = '{$tanggalbayar}' + WHERE SupplierInstallmentID = $orderid"; + $querybill = $this->db_onedev->query($sqlbill); + if (!$querybill) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('update tanggal bayar installment'); + exit(); + } + } else { + $sqlbill = "UPDATE supplier_invoice SET SupplierInvoiceDraftPaymentDate = '{$tanggalbayar}' WHERE SupplierInvoiceID = $orderid"; - $querybill = $this->db_onedev->query($sqlbill); + $querybill = $this->db_onedev->query($sqlbill); + if (!$querybill) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('update tanggal bayar invoice'); + exit(); + } + } //echo $this->db_onedev->last_query(); - - - $sql = "SELECT * FROM supplier_payment + $sql = 'SELECT * FROM supplier_payment JOIN supplier_invoice ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID JOIN m_user ON M_UserID = SupplierPaymentUserID - WHERE SupplierPaymentID = ?"; + WHERE SupplierPaymentID = ?'; $query = $this->db_onedev->query($sql, [$headerid]); + if (!$query) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('failed select data supplier payment'); + exit(); + } $row = $query->row_array(); - $sql = "SELECT * FROM supplier_payment_detail - WHERE SupplierPaymentDetailSupplierPaymentID = ?"; + $sql = 'SELECT * FROM supplier_payment_detail + WHERE SupplierPaymentDetailSupplierPaymentID = ?'; $query = $this->db_onedev->query($sql, [$headerid]); + if (!$query) { + $this->db_onedev->trans_rollback(); + $this->sys_error_db('failed select data supplier payment detail'); + exit(); + } $rows = $query->row_array(); $data = array( - "header" => $row, - "details" => $rows + 'header' => $row, + 'details' => $rows, ); - $message = "Nomor Pembayaran Faktur: " . $row["SupplierPaymentNumber"] . " berhasil diubah oleh " . $row["M_UserUsername"]; - $this->insert_act_log("PF", "NEW", $message, $headerid, $this->safeJsonEncode($data), $xuserid); + $message = + 'Nomor Pembayaran Faktur: ' + . $row['SupplierPaymentNumber'] + . ' berhasil diubah oleh ' + . $row['M_UserUsername']; + $this->insert_act_log('PF', 'NEW', $message, $headerid, $this->safeJsonEncode($data), $xuserid); + $this->db_onedev->trans_commit(); - $xdata = $this->db_onedev->query("SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}")->row(); + $xdata = $this->db_onedev->query( + "SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}" + )->row(); $result = array( - "total" => count($rows), - "records" => array('data' => $xdata) + 'total' => count($rows), + 'records' => array('data' => $xdata), ); $this->sys_ok($result); - exit; + exit(); } function delete_note() { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } //# ambil parameter input @@ -795,20 +947,20 @@ ORDER BY coaAccountNo ASC"; $prmnota = $prm['nota']; $headerid = $prmnota['note_id']; - $sql = "SELECT * FROM supplier_payment + $sql = 'SELECT * FROM supplier_payment JOIN m_user ON M_UserID = SupplierPaymentUserID - WHERE SupplierPaymentID = ?"; + WHERE SupplierPaymentID = ?'; $query = $this->db_onedev->query($sql, [$headerid]); $row = $query->row_array(); - $sql = "SELECT * FROM supplier_payment_detail - WHERE SupplierPaymentDetailSupplierPaymentID = ?"; + $sql = 'SELECT * FROM supplier_payment_detail + WHERE SupplierPaymentDetailSupplierPaymentID = ?'; $query = $this->db_onedev->query($sql, [$headerid]); $rows = $query->row_array(); $data = array( - "header" => $row, - "details" => $rows + 'header' => $row, + 'details' => $rows, ); $sql = "UPDATE supplier_payment @@ -817,8 +969,8 @@ ORDER BY coaAccountNo ASC"; //echo $sql; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_payment delete"); - exit; + $this->sys_error_db('supplier_payment delete'); + exit(); } $sql = "UPDATE supplier_payment_detail @@ -827,8 +979,8 @@ ORDER BY coaAccountNo ASC"; //echo $sql; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_payment_detail delete"); - exit; + $this->sys_error_db('supplier_payment_detail delete'); + exit(); } $sql = "UPDATE supplier_invoice @@ -837,8 +989,8 @@ ORDER BY coaAccountNo ASC"; //echo $sql; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_invoice delete"); - exit; + $this->sys_error_db('supplier_invoice delete'); + exit(); } $sql = "UPDATE supplier_invoice_detail @@ -847,26 +999,30 @@ ORDER BY coaAccountNo ASC"; //echo $sql; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_invoice_detail delete"); - exit; + $this->sys_error_db('supplier_invoice_detail delete'); + exit(); } - $message = "Nomor Pembayaran Faktur: " . $row["SupplierPaymentNumber"] . " telah dihapus oleh " . $row["M_UserUsername"]; - $this->insert_act_log("PF", "DELETE", $message, $headerid, $this->safeJsonEncode($data), $xuserid); + $message = + 'Nomor Pembayaran Faktur: ' + . $row['SupplierPaymentNumber'] + . ' telah dihapus oleh ' + . $row['M_UserUsername']; + $this->insert_act_log('PF', 'DELETE', $message, $headerid, $this->safeJsonEncode($data), $xuserid); $result = array( - "total" => 1, - "records" => array('prm' => $prm) + 'total' => 1, + 'records' => array('prm' => $prm), ); $this->sys_ok($result); - exit; + exit(); } function edit_note() { //# cek token valid - if (! $this->isLogin) { - $this->sys_error("Invalid Token"); - exit; + if (!$this->isLogin) { + $this->sys_error('Invalid Token'); + exit(); } //# ambil parameter input @@ -883,25 +1039,26 @@ ORDER BY coaAccountNo ASC"; $datas_log = []; $messages_log = []; - $sql = "SELECT * + $sql = 'SELECT * FROM supplier_payment - WHERE SupplierPaymentID = ?"; + WHERE SupplierPaymentID = ?'; $query = $this->db_onedev->query($sql, [$id]); if (!$query) { $this->db_onedev->trans_rollback(); - $this->sys_error_db("supplier payment", $this->db_onedev); - exit; + $this->sys_error_db('supplier payment', $this->db_onedev); + exit(); } $row = $query->row_array(); - if ($row["SupplierPaymentAmount"] != $amount_new) { - $messages_log[] = "Perubahan pembayaran : " . $row["SupplierPaymentAmount"] . " menjadi " . $amount_new; + if ($row['SupplierPaymentAmount'] != $amount_new) { + $messages_log[] = 'Perubahan pembayaran : ' . $row['SupplierPaymentAmount'] . ' menjadi ' . $amount_new; } - if ($row["SupplierPaymentNote"] != $keterangan) { - $messages_log[] = "Perubahan keterangan : " . $row["SupplierPaymentNote"] . " menjadi " . $keterangan; + if ($row['SupplierPaymentNote'] != $keterangan) { + $messages_log[] = 'Perubahan keterangan : ' . $row['SupplierPaymentNote'] . ' menjadi ' . $keterangan; } - if ($row["SupplierPaymentCoaID"] != $paymenttype) { - $messages_log[] = "Perubahan tipe pembayaran id : " . $row["SupplierPaymentCoaID"] . " menjadi " . $paymenttype; + if ($row['SupplierPaymentCoaID'] != $paymenttype) { + $messages_log[] = + 'Perubahan tipe pembayaran id : ' . $row['SupplierPaymentCoaID'] . ' menjadi ' . $paymenttype; } $datas_log['header'] = $row; @@ -915,8 +1072,8 @@ ORDER BY coaAccountNo ASC"; //echo $sql; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_payment edit"); - exit; + $this->sys_error_db('supplier_payment edit'); + exit(); } $sql = "UPDATE supplier_payment_detail @@ -926,8 +1083,8 @@ ORDER BY coaAccountNo ASC"; //echo $sql; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_payment_detail edit"); - exit; + $this->sys_error_db('supplier_payment_detail edit'); + exit(); } $sql = "UPDATE supplier_invoice @@ -936,8 +1093,8 @@ ORDER BY coaAccountNo ASC"; //echo $sql; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_invoice edit"); - exit; + $this->sys_error_db('supplier_invoice edit'); + exit(); } $sql = "UPDATE supplier_invoice_detail @@ -946,29 +1103,29 @@ ORDER BY coaAccountNo ASC"; //echo $sql; $query = $this->db_onedev->query($sql); if (!$query) { - $this->sys_error_db("supplier_invoice_detail edit"); - exit; + $this->sys_error_db('supplier_invoice_detail edit'); + exit(); } if (count($messages_log) > 0) { - $message = "Perubahan Pembayaran Faktur: " . $row["SupplierPaymentNumber"] . "\n"; + $message = 'Perubahan Pembayaran Faktur: ' . $row['SupplierPaymentNumber'] . "\n"; $message .= implode("\n", $messages_log); } else { - $message = "Pembayaran Faktur: " . $row["SupplierPaymentNumber"] . " tanpa perubahan"; + $message = 'Pembayaran Faktur: ' . $row['SupplierPaymentNumber'] . ' tanpa perubahan'; } $datas_log = $this->convertNumericValuesToStrings($datas_log); - $this->insert_act_log("PF", "EDIT", $message, $id, $this->safeJsonEncode($datas_log), $xuserid); + $this->insert_act_log('PF', 'EDIT', $message, $id, $this->safeJsonEncode($datas_log), $xuserid); $result = array( - "total" => 1, - "records" => array('prm' => $prm) + 'total' => 1, + 'records' => array('prm' => $prm), ); $this->sys_ok($result); - exit; + exit(); } function insert_act_log($code, $status, $description, $refId, $data, $userId) { - $sql = "INSERT INTO user_activity( + $sql = 'INSERT INTO user_activity( UserActivityCode, UserActivityStatus, UserActivityDescription, @@ -976,11 +1133,19 @@ ORDER BY coaAccountNo ASC"; UserActivityData, UserActivityUserID, UserActivityCreated) - VALUES (?,?,?,?,?,?,?)"; - $query = $this->db_onedev->query($sql, [$code, $status, $description, $refId, $data, $userId, date("Y-m-d H:i:s")]); + VALUES (?,?,?,?,?,?,?)'; + $query = $this->db_onedev->query($sql, [ + $code, + $status, + $description, + $refId, + $data, + $userId, + date('Y-m-d H:i:s'), + ]); if (!$query) { - $this->sys_error_db("user activity", $this->db_onedev); - exit; + $this->sys_error_db('user activity', $this->db_onedev); + exit(); } } @@ -992,7 +1157,7 @@ ORDER BY coaAccountNo ASC"; // Cek apakah terjadi error saat encode if (json_last_error() !== JSON_ERROR_NONE) { $errorMsg = json_last_error_msg(); - error_log("JSON encode error: " . $errorMsg); + error_log('JSON encode error: ' . $errorMsg); // Lakukan sanitasi dan perbaikan data $fixedData = $this->fixJsonEncodeIssues($data, $errorMsg); @@ -1002,7 +1167,7 @@ ORDER BY coaAccountNo ASC"; // Jika masih error, log dan kembalikan objek kosong if (json_last_error() !== JSON_ERROR_NONE) { - error_log("Failed to fix JSON encode issues: " . json_last_error_msg()); + error_log('Failed to fix JSON encode issues: ' . json_last_error_msg()); // Kembalikan objek kosong jika masih gagal return '{}'; } @@ -1054,7 +1219,7 @@ ORDER BY coaAccountNo ASC"; if (is_array($data)) { foreach ($data as $key => $value) { if (is_float($value) && (is_nan($value) || is_infinite($value))) { - $data[$key] = (string)$value; // Konversi ke string + $data[$key] = (string) $value; // Konversi ke string } else if (is_array($value)) { $data[$key] = $this->fixInfNanIssues($value); } @@ -1068,7 +1233,7 @@ ORDER BY coaAccountNo ASC"; { // Batasi kedalaman rekursi untuk menghindari infinite loop if ($depth > 50) { - return "[MAX_DEPTH_REACHED]"; + return '[MAX_DEPTH_REACHED]'; } if (is_array($data)) { @@ -1094,9 +1259,9 @@ ORDER BY coaAccountNo ASC"; if (is_array($value)) { $data[$key] = $this->convertNumericValuesToStrings($value); } else if (is_numeric($value)) { - $data[$key] = (string)$value; + $data[$key] = (string) $value; } else if (is_bool($value)) { - $data[$key] = $value ? "true" : "false"; + $data[$key] = $value ? 'true' : 'false'; } } }