feature: payment instruction & cashier case cicilan dan downpayment
This commit is contained in:
@@ -1127,11 +1127,14 @@ class ReceiveItemPOAsset extends MY_Controller
|
|||||||
PurchaseOrderSummaryQty as QtyAllPO,
|
PurchaseOrderSummaryQty as QtyAllPO,
|
||||||
PurchaseOrderSummaryTotal as TotalAllPO,
|
PurchaseOrderSummaryTotal as TotalAllPO,
|
||||||
PurchaseOrderDiscountPercent AS DiscPOPercent,
|
PurchaseOrderDiscountPercent AS DiscPOPercent,
|
||||||
PurchaseOrderDiscountAmount AS DiscPORupiah
|
PurchaseOrderDiscountAmount AS DiscPORupiah,
|
||||||
|
M_ItemItem_CategoryID
|
||||||
FROM receive_order_po_detail
|
FROM receive_order_po_detail
|
||||||
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
||||||
JOIN purchase_order_summary ON ReceiveOrderPoDetailPurchaseOrderSummaryID = PurchaseOrderSummaryID
|
JOIN purchase_order_summary ON ReceiveOrderPoDetailPurchaseOrderSummaryID = PurchaseOrderSummaryID
|
||||||
AND PurchaseOrderSummaryIsActive = 'Y'
|
AND PurchaseOrderSummaryIsActive = 'Y'
|
||||||
|
JOIN m_item ON M_ItemID = ReceiveOrderPoItemID
|
||||||
|
AND M_ItemIsActive = 'Y'
|
||||||
WHERE ReceiveOrderPoDetailReceiveOrderPoID = ?
|
WHERE ReceiveOrderPoDetailReceiveOrderPoID = ?
|
||||||
AND ReceiveOrderPoDetailIsActive='Y'
|
AND ReceiveOrderPoDetailIsActive='Y'
|
||||||
GROUP BY ReceiveOrderPoDetailID";
|
GROUP BY ReceiveOrderPoDetailID";
|
||||||
@@ -1268,13 +1271,13 @@ class ReceiveItemPOAsset extends MY_Controller
|
|||||||
|
|
||||||
/* INSERT table jurnal tx item */
|
/* INSERT table jurnal tx item */
|
||||||
$sql_jurnaltx = "INSERT INTO jurnal_tx (
|
$sql_jurnaltx = "INSERT INTO jurnal_tx (
|
||||||
jurnalTxJurnalID,
|
jurnalTxJurnalID,
|
||||||
jurnalTxCoaID,
|
jurnalTxCoaID,
|
||||||
jurnalTxDescription,
|
jurnalTxDescription,
|
||||||
jurnalTxDebit,
|
jurnalTxDebit,
|
||||||
jurnalTxCredit,
|
jurnalTxCredit,
|
||||||
jurnalTxM_UserID
|
jurnalTxM_UserID
|
||||||
) VALUES (?,?,?,?,?,?)";
|
) VALUES (?,?,?,?,?,?)";
|
||||||
$que_jurnaltx = $this->db->query($sql_jurnaltx, [
|
$que_jurnaltx = $this->db->query($sql_jurnaltx, [
|
||||||
$jurnalID,
|
$jurnalID,
|
||||||
$coa_asset['Fa_ClassCoaID'],
|
$coa_asset['Fa_ClassCoaID'],
|
||||||
@@ -1291,14 +1294,14 @@ class ReceiveItemPOAsset extends MY_Controller
|
|||||||
|
|
||||||
/* INSERT table jurnal addon item */
|
/* INSERT table jurnal addon item */
|
||||||
$sql_jurnaladdon = "INSERT INTO jurnal_addon (
|
$sql_jurnaladdon = "INSERT INTO jurnal_addon (
|
||||||
jurnalAddOnJurnalID,
|
jurnalAddOnJurnalID,
|
||||||
jurnalAddOnJurnalTxID,
|
jurnalAddOnJurnalTxID,
|
||||||
jurnalAddOnCode,
|
jurnalAddOnCode,
|
||||||
jurnalAddOnValue,
|
jurnalAddOnValue,
|
||||||
jurnalAddOnM_ItemID,
|
jurnalAddOnM_ItemID,
|
||||||
jurnalAddOnCreated,
|
jurnalAddOnCreated,
|
||||||
jurnalAddOnCreatedUserID
|
jurnalAddOnCreatedUserID
|
||||||
) VALUES (?,?,'PONUMB',?,?,NOW(),?)";
|
) VALUES (?,?,'PONUMB',?,?,NOW(),?)";
|
||||||
$que_jurnaladdon = $this->db->query($sql_jurnaladdon, [
|
$que_jurnaladdon = $this->db->query($sql_jurnaladdon, [
|
||||||
$jurnalID,
|
$jurnalID,
|
||||||
$jurnalTXID,
|
$jurnalTXID,
|
||||||
@@ -1354,7 +1357,7 @@ class ReceiveItemPOAsset extends MY_Controller
|
|||||||
throw new Exception("[Error] failed get account diskon", 1);
|
throw new Exception("[Error] failed get account diskon", 1);
|
||||||
}
|
}
|
||||||
$coa_diskon = $que_coadiskon->row_array();
|
$coa_diskon = $que_coadiskon->row_array();
|
||||||
foreach ($input_diskon as $key => $val) {
|
foreach ($input_diskon as $idx => $val) {
|
||||||
if (doubleval($val) <= 0.00) {
|
if (doubleval($val) <= 0.00) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1397,10 +1400,199 @@ class ReceiveItemPOAsset extends MY_Controller
|
|||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
throw new Exception("[Error] save diskon prorate", 1);
|
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 #
|
# 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 (
|
$sql_grni = "INSERT INTO jurnal_tx (
|
||||||
jurnalTxJurnalID,
|
jurnalTxJurnalID,
|
||||||
jurnalTxCoaID,
|
jurnalTxCoaID,
|
||||||
@@ -1533,10 +1725,11 @@ class ReceiveItemPOAsset extends MY_Controller
|
|||||||
SupplierInvoiceGrandTotal,
|
SupplierInvoiceGrandTotal,
|
||||||
SupplierInvoiceUnpaid,
|
SupplierInvoiceUnpaid,
|
||||||
SupplierInvoiceNote,
|
SupplierInvoiceNote,
|
||||||
|
SupplierInvoiceIsInstallment,
|
||||||
SupplierInvoiceReceiveDate,
|
SupplierInvoiceReceiveDate,
|
||||||
SupplierInvoiceReceivedBy,
|
SupplierInvoiceReceivedBy,
|
||||||
SupplierInvoiceCreatedUserID
|
SupplierInvoiceCreatedUserID
|
||||||
) VALUES (?,?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?,NOW(),?,?)";
|
) VALUES (?,?,NOW(),?,?,?,?,?,?,?,?,?,?,?,?,'Y',NOW(),?,?)";
|
||||||
$que_insert_pi = $this->db->query($sql_insert_pi, [
|
$que_insert_pi = $this->db->query($sql_insert_pi, [
|
||||||
$num_pi,
|
$num_pi,
|
||||||
$data_ro['ReceiveOrderPoID'],
|
$data_ro['ReceiveOrderPoID'],
|
||||||
|
|||||||
@@ -1705,22 +1705,38 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_coa_inv = "SELECT
|
$sql_invcoa = "SELECT
|
||||||
CoaMapInventarisCoaID,
|
COALESCE(
|
||||||
CoaMapInventarisCoaNo,
|
i.M_InventarisItemCoaMappingID,
|
||||||
CoaMapInventarisCoaDesc
|
g.M_InventarisCoaMappingID
|
||||||
FROM coa_map_inventaris
|
) AS MappingID,
|
||||||
WHERE CoaMapInventarisM_InventarisGolID = ?
|
COALESCE(
|
||||||
AND CoaMapInventarisIsActive = 'Y'";
|
i.M_InventarisItemCoaMappingCoaInventarisID,
|
||||||
$que_coa_inv = $this->db->query($sql_coa_inv, [$item_cek['M_ItemM_InventarisGolID']]);
|
g.M_InventarisCoaMappingCoaInventarisID
|
||||||
if (!$que_coa_inv) {
|
) 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->db->trans_rollback();
|
||||||
$this->sys_error_db("[Error] failed to get coa biaya item inventaris");
|
$this->sys_error_db("[Error] failed to get coa biaya item inventaris");
|
||||||
exit;
|
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->db->trans_rollback();
|
||||||
$this->sys_error_db("[Error] coa gol inventaris not found");
|
$this->sys_error_db("[Error] coa gol inventaris not found");
|
||||||
exit;
|
exit;
|
||||||
@@ -1740,8 +1756,8 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
) VALUES (?,?,?,?,?,?)";
|
) VALUES (?,?,?,?,?,?)";
|
||||||
$que_tx_jurnal = $this->db->query($sql_tx_jurnal, [
|
$que_tx_jurnal = $this->db->query($sql_tx_jurnal, [
|
||||||
$jurnal_ID,
|
$jurnal_ID,
|
||||||
$iteminv_coa['CoaMapInventarisCoaID'],
|
$iteminv_coa['CoaInventarisID'],
|
||||||
$iteminv_coa['CoaMapInventarisCoaDesc'],
|
$iteminv_coa['CoaInventarisDesc'],
|
||||||
$debet,
|
$debet,
|
||||||
0,
|
0,
|
||||||
$user['M_UserID']
|
$user['M_UserID']
|
||||||
@@ -1754,7 +1770,7 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
}
|
}
|
||||||
$juranl_tx_ID = $this->db->insert_id();
|
$juranl_tx_ID = $this->db->insert_id();
|
||||||
$each_desc[] = "- Add detail Jurnal debet {$item_cek['M_ItemDesc']}
|
$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 #
|
# INSERT JURNAL ADDON #
|
||||||
$sql_addon_jurnal = "INSERT INTO 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");
|
$this->sys_error_db("[Error] insert update stock");
|
||||||
exit;
|
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 {
|
} else {
|
||||||
$sql_insert_stock = "INSERT INTO stock (
|
$sql_insert_stock = "INSERT INTO stock (
|
||||||
StockWarehouseAlmariID,
|
StockWarehouseAlmariID,
|
||||||
@@ -1985,23 +1987,9 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stockID = $this->db->insert_id();
|
$stock_ID = $this->db->insert_id();
|
||||||
$stock_qty_ori = 0;
|
$stock_qty_ori = 0;
|
||||||
$stock_qty_end = intval($batch['qty']);
|
$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
|
// insert stock card
|
||||||
|
|||||||
@@ -1,78 +1,55 @@
|
|||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# FILE : PurchaseInvoiceInstallment.http
|
# FILE : PurchaseInvoiceInstallment.http
|
||||||
# MODUL : Scheduler — Generate Purchase Invoice Cicilan Aset
|
# MODUL : Scheduler — Generate Supplier Installment Cicilan Aset
|
||||||
# ============================================================
|
# ============================================================
|
||||||
#
|
#
|
||||||
# DESKRIPSI
|
# DESKRIPSI
|
||||||
# ---------
|
# ---------
|
||||||
# File ini berisi kumpulan HTTP request untuk menguji endpoint
|
# File ini berisi HTTP request untuk menguji endpoint scheduler
|
||||||
# scheduler yang secara otomatis membuat Purchase Invoice (PI)
|
# yang secara otomatis membuat baris cicilan ke tabel
|
||||||
# cicilan bulanan berdasarkan kontrak aset aktif.
|
# supplier_installment setiap bulan.
|
||||||
#
|
#
|
||||||
# CARA PAKAI
|
# CARA PAKAI
|
||||||
# ----------
|
# ----------
|
||||||
# 1. Gunakan ekstensi "REST Client" di VS Code (humao.rest-client)
|
# 1. Gunakan ekstensi "REST Client" di VS Code (humao.rest-client)
|
||||||
# atau tool sejenis (IntelliJ HTTP Client, Postman, dll).
|
# atau tool sejenis (IntelliJ HTTP Client, Postman, dll).
|
||||||
# 2. Ganti nilai @host sesuai environment (local / staging / prod).
|
# 2. Ganti nilai @host sesuai environment.
|
||||||
# 3. Klik "Send Request" di atas tiap blok ### untuk menjalankan
|
# 3. Klik "Send Request" di atas tiap blok ###
|
||||||
# request tersebut secara individual.
|
|
||||||
# 4. Jalankan request secara BERURUTAN sesuai urutan yang disarankan
|
|
||||||
# (lihat keterangan tiap endpoint di bawah).
|
|
||||||
#
|
#
|
||||||
# ALUR PENGGUNAAN YANG DISARANKAN
|
# ALUR
|
||||||
# --------------------------------
|
# ----
|
||||||
# [1] ListEligibleContracts → Lihat kontrak mana saja yang akan diproses
|
# [1] GenerateMonthlyInvoices → Jalankan proses generate installment
|
||||||
# [2] GenerateMonthlyInvoices → Jalankan proses generate PI cicilan sekaligus
|
|
||||||
# [3] InsertSupplierInvoice → (Opsional) Insert manual 1 PI jika diperlukan
|
|
||||||
#
|
#
|
||||||
# CATATAN
|
# CATATAN
|
||||||
# -------
|
# -------
|
||||||
# - startDate & endDate menentukan periode bulan yang diproses.
|
# - Default periode: bulan berjalan (tanggal 1 s/d akhir bulan)
|
||||||
# Biasanya diisi dengan tanggal awal dan akhir bulan berjalan.
|
# - Aman dijalankan ulang — dedup berdasarkan PO + bulan mencegah
|
||||||
# - Scheduler ini AMAN dijalankan ulang (idempotent). Kontrak yang
|
# duplikasi
|
||||||
# sudah punya PI di bulan yang sama akan dilewati otomatis.
|
# - Tidak membuat jurnal — jurnal dibuat saat pembayaran cashier
|
||||||
# - userID pada InsertSupplierInvoice akan diabaikan; sistem
|
# - Tidak update kontrak — InstallmentPaid diupdate saat pembayaran
|
||||||
# mengambil userID dari PurchaseOrderAssetContractCreatedUserID.
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
@host = https://accone.aplikasi.web.id/one-api
|
@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
|
# Satu request ini akan:
|
||||||
# kontrak mana saja yang akan dibuatkan PI pada periode ini.
|
# 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,
|
# Response:
|
||||||
# status GRNI, dan apakah PI bulan ini sudah ada atau belum.
|
# - 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
|
### [1] Generate installment untuk periode tertentu
|
||||||
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
|
|
||||||
POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
@@ -81,47 +58,8 @@ Content-Type: application/json
|
|||||||
"endDate": "2026-07-31"
|
"endDate": "2026-07-31"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================================
|
### [1a] Generate installment bulan berjalan (tanpa parameter)
|
||||||
# [3] INSERT MANUAL SATU PI (INTERNAL / DEBUG)
|
POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
||||||
# ============================================================
|
|
||||||
# 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
|
|
||||||
Content-Type: application/json
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,20 +3,19 @@
|
|||||||
/**
|
/**
|
||||||
* PurchaseInvoiceInstallment
|
* PurchaseInvoiceInstallment
|
||||||
*
|
*
|
||||||
* Digunakan oleh CRON untuk membuat Purchase Invoice (PI) cicilan aset
|
* CRON scheduler untuk membuat baris cicilan otomatis ke tabel supplier_installment
|
||||||
* secara otomatis setiap bulan berdasarkan kontrak yang aktif.
|
* setiap bulan berdasarkan kontrak aset yang aktif dan belum lunas.
|
||||||
*
|
*
|
||||||
* Endpoint utama:
|
* Endpoint:
|
||||||
* POST /scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
* POST /scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
||||||
* POST /scheduler/PurchaseInvoiceInstallment/CurlGenerateMonthlyInvoices
|
|
||||||
*/
|
*/
|
||||||
class PurchaseInvoiceInstallment extends MY_Controller
|
class PurchaseInvoiceInstallment extends MY_Controller
|
||||||
{
|
{
|
||||||
var $db;
|
var $db;
|
||||||
var $baseUrl = "https://accone.aplikasi.web.id/one-api/";
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
echo "Purchase Invoice Installment — Auto Generate PI Cicilan Aset";
|
echo "Purchase Invoice Installment — Auto Generate Installment Cicilan Aset";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct()
|
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
|
* Creates supplier_installment rows for all eligible contracts this month.
|
||||||
* dan belum lunas pada bulan yang ditentukan.
|
* 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):
|
* Called by CRON daily at 1:00 AM.
|
||||||
* - startDate : Tanggal awal periode (format YYYY-MM-DD). Default: awal bulan ini.
|
* Defaults to current month if no startDate/endDate provided.
|
||||||
* - 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
|
|
||||||
*/
|
*/
|
||||||
public function GenerateMonthlyInvoices()
|
public function GenerateMonthlyInvoices()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$para = $this->sys_input;
|
$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);
|
|
||||||
|
|
||||||
$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"]
|
? $para["startDate"]
|
||||||
: (isset($para["date"]) && $para["date"] != "" ? date("Y-m-01", strtotime($para["date"])) : date("Y-m-01"));
|
: date("Y-m-01");
|
||||||
$endDate = isset($para["endDate"]) && $para["endDate"] != ""
|
|
||||||
|
$endDate = !empty($para["endDate"])
|
||||||
? $para["endDate"]
|
? $para["endDate"]
|
||||||
: (isset($para["date"]) && $para["date"] != "" ? date("Y-m-t", strtotime($para["date"])) : date("Y-m-t"));
|
: date("Y-m-t");
|
||||||
// Validasi format tanggal
|
|
||||||
if (!$this->isValidDate($startDate) || !$this->isValidDate($endDate)) {
|
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)) {
|
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
|
// ── Steps 1–5: Get eligible contracts ────────────────────
|
||||||
$monthStart = $startDate;
|
$eligible = $this->getEligibleInstallments($startDate, $endDate);
|
||||||
$monthEnd = $endDate;
|
|
||||||
$dayOfMonth = (int) date("d", strtotime($endDate));
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
$created = [];
|
||||||
// Ambil semua kontrak cicilan yang memenuhi syarat pada bulan ini
|
$inserted = 0;
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
$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
|
|
||||||
|
|
||||||
-- Pastikan PO sudah Approved dan aktif
|
$this->db->trans_begin();
|
||||||
JOIN purchase_order po
|
|
||||||
ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID
|
|
||||||
AND po.PurchaseOrderIsActive = 'Y'
|
|
||||||
AND po.PurchaseOrderStatus = 'Approved'
|
|
||||||
|
|
||||||
JOIN (
|
foreach ($eligible as $row) {
|
||||||
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
|
|
||||||
|
|
||||||
-- Ambil 1 item PO pertama sebagai referensi baris detail PI
|
$amount = (float) $row["PurchaseOrderAssetContractInstallmentPayAmount"];
|
||||||
LEFT JOIN (
|
$dayOfMonth = (int) ($row["PurchaseOrderAssetContractInstallmentDate"] ?? 1);
|
||||||
SELECT ps0.*
|
$lastDay = (int) date("t", strtotime($endDate));
|
||||||
FROM purchase_order_summary ps0
|
$dayOfMonth = min($dayOfMonth, $lastDay);
|
||||||
JOIN (
|
$installDate = date("Y-m", strtotime($endDate)) . "-" . str_pad($dayOfMonth, 2, "0", STR_PAD_LEFT);
|
||||||
SELECT
|
$dueDate = date("Y-m-d", strtotime($installDate . " +7 days"));
|
||||||
PurchaseOrderSummaryPurchaseOrderID,
|
$createdBy = (int) ($row["PurchaseOrderAssetContractCreatedUserID"] ?? $userID);
|
||||||
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'
|
// ── Step 6: INSERT supplier_installment ──────────────
|
||||||
AND c.PurchaseOrderAssetContractStatus = 'belum lunas'
|
$sql = "INSERT INTO supplier_installment (
|
||||||
-- Hanya kontrak yang ada nilai cicilannya
|
SupplierInstallmentPurchaseOrderID,
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPayAmount, 0) > 0
|
SupplierInstallmentSupplierID,
|
||||||
-- Hanya kontrak yang belum selesai seluruh cicilannya
|
SupplierInstallmentSupplierInvoiceID,
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPaid, 0) < IFNULL(c.PurchaseOrderAssetContractInstallmentNumber, 0)
|
SupplierInstallmentAmount,
|
||||||
-- Kontrak sudah mulai sebelum atau pada akhir bulan ini
|
SupplierInstallmentDate,
|
||||||
AND DATE(c.PurchaseOrderAssetContractStartDate) <= DATE(?)
|
SupplierInstallmentDueDate,
|
||||||
-- Kontrak belum berakhir (atau tidak ada tanggal akhir)
|
SupplierInstallmentPaymentID,
|
||||||
AND (
|
SupplierInstallmentStatus,
|
||||||
c.PurchaseOrderAssetContractEndDate IS NULL
|
SupplierInstallmentIsLunas,
|
||||||
OR DATE(c.PurchaseOrderAssetContractEndDate) >= DATE(?)
|
SupplierInstallmentIsActive,
|
||||||
)
|
SupplierInstallmentCreated,
|
||||||
-- Tanggal jatuh tempo cicilan sudah melewati atau sama dengan hari ini
|
SupplierInstallmentCreatedUserID
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentDate, 1) <= ?";
|
) 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 (!$que) {
|
||||||
if (!$qryKontrak) {
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db("Gagal mengambil daftar kontrak cicilan dari database.");
|
$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;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$berhasil = []; // PI yang berhasil dibuat
|
$this->db->trans_commit();
|
||||||
$dilewati = []; // PI yang dilewati beserta alasannya
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// 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([
|
$this->sys_ok([
|
||||||
"startDate" => $startDate,
|
"startDate" => $startDate,
|
||||||
"endDate" => $endDate,
|
"endDate" => $endDate,
|
||||||
"periodeAwal" => $monthStart,
|
"totalEligible" => count($eligible),
|
||||||
"periodeAkhir" => $monthEnd,
|
"totalInserted" => $inserted,
|
||||||
"totalDibuat" => count($berhasil),
|
"created" => $created
|
||||||
"totalDilewati" => count($dilewati),
|
|
||||||
"daftarDibuat" => $berhasil,
|
|
||||||
"daftarDilewati" => $dilewati
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
if ($this->db->trans_status() === false) {
|
if ($this->db->trans_status() === false) {
|
||||||
$this->db->trans_rollback();
|
$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.
|
* Ambil data user berdasarkan userID untuk keperluan CRON.
|
||||||
* Jika user tidak ditemukan, kembalikan data default (tanpa branch/regional).
|
* 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);
|
$d = DateTime::createFromFormat("Y-m-d", $tanggal);
|
||||||
return $d && $d->format("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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Billv2 extends MY_Controller {
|
|||||||
$offset = ($params['currentpage'] - 1) * $limit;
|
$offset = ($params['currentpage'] - 1) * $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── UNION base — invoice branch + downpayment branch ────
|
// ── UNION base — invoice + downpayment + installment ───
|
||||||
$sql_base = "
|
$sql_base = "
|
||||||
SELECT
|
SELECT
|
||||||
sp.SupplierPaymentID,
|
sp.SupplierPaymentID,
|
||||||
@@ -76,7 +76,33 @@ class Billv2 extends MY_Controller {
|
|||||||
ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID
|
ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID
|
||||||
JOIN purchase_order po
|
JOIN purchase_order po
|
||||||
ON po.PurchaseOrderID = dp.SupplierDownpaymentPurchasOrderID
|
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 ───────
|
// ── Outer: common filters + ordering + pagination ───────
|
||||||
$sql_data = "
|
$sql_data = "
|
||||||
@@ -97,8 +123,7 @@ class Billv2 extends MY_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ── COUNT — wrap UNION in outer filter ──────────────────
|
// ── COUNT — wrap UNION in outer filter ──────────────────
|
||||||
$sql_total = "
|
$sql_total = "SELECT COUNT(*) AS total FROM ($sql_base) AS combined
|
||||||
SELECT COUNT(*) AS total FROM ($sql_base) AS combined
|
|
||||||
WHERE SupplierPaymentIsActive = 'Y'
|
WHERE SupplierPaymentIsActive = 'Y'
|
||||||
AND SupplierPaymentNumber LIKE ?
|
AND SupplierPaymentNumber LIKE ?
|
||||||
AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?))
|
AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?))
|
||||||
@@ -118,7 +143,6 @@ class Billv2 extends MY_Controller {
|
|||||||
];
|
];
|
||||||
|
|
||||||
$this->sys_ok($output);
|
$this->sys_ok($output);
|
||||||
exit;
|
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
$message = $exc->getMessage();
|
$message = $exc->getMessage();
|
||||||
$code = $exc->getCode();
|
$code = $exc->getCode();
|
||||||
@@ -143,7 +167,8 @@ class Billv2 extends MY_Controller {
|
|||||||
// ── Detect payment type ──────────────────────────────────
|
// ── Detect payment type ──────────────────────────────────
|
||||||
$sql_type = "SELECT
|
$sql_type = "SELECT
|
||||||
SupplierPaymentSupplierInvoiceID,
|
SupplierPaymentSupplierInvoiceID,
|
||||||
SupplierPaymentSupplierDownpaymentID
|
SupplierPaymentSupplierDownpaymentID,
|
||||||
|
SupplierPaymentSupplierInstallmentID
|
||||||
FROM supplier_payment
|
FROM supplier_payment
|
||||||
WHERE SupplierPaymentID = ? AND SupplierPaymentIsActive = 'Y'";
|
WHERE SupplierPaymentID = ? AND SupplierPaymentIsActive = 'Y'";
|
||||||
|
|
||||||
@@ -206,7 +231,7 @@ class Billv2 extends MY_Controller {
|
|||||||
$data['detail'] = $que_detail->result_array();
|
$data['detail'] = $que_detail->result_array();
|
||||||
|
|
||||||
// ── DOWNPAYMENT branch ──────────────────────────────────
|
// ── DOWNPAYMENT branch ──────────────────────────────────
|
||||||
} else {
|
} elseif ($payment['SupplierPaymentSupplierDownpaymentID'] > 0) {
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
dp.SupplierDownpaymentPurchasOrderID,
|
dp.SupplierDownpaymentPurchasOrderID,
|
||||||
dp.SupplierDownpaymentAmount AS SupplierInvoiceSubTotal,
|
dp.SupplierDownpaymentAmount AS SupplierInvoiceSubTotal,
|
||||||
@@ -255,6 +280,51 @@ class Billv2 extends MY_Controller {
|
|||||||
throw new Exception('failed to get dp detail', 2);
|
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();
|
$data['detail'] = $que_detail->result_array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
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,
|
PurchaseOrderNumber as tagihan_number,
|
||||||
jurnalTxDescription as pasien,
|
jurnalTxDescription as pasien,
|
||||||
jurnalTxCredit as tagihan_total,
|
jurnalTxCredit as tagihan_total,
|
||||||
@@ -135,14 +212,20 @@ class Bill extends MY_Controller
|
|||||||
jurnalTxID SupplierInvoiceDetailID,
|
jurnalTxID SupplierInvoiceDetailID,
|
||||||
PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID
|
PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
|
JOIN receive_order_po
|
||||||
|
ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
||||||
|
JOIN receive_order_po_detail
|
||||||
|
ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID
|
||||||
JOIN purchase_order
|
JOIN purchase_order
|
||||||
ON SupplierInvoicePurchaseOrderID = PurchaseOrderID
|
ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
||||||
JOIN jurnal_addon
|
JOIN jurnal_addon
|
||||||
ON jurnalAddOnValue = SupplierInvoiceNumber
|
ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
|
AND jurnalAddOnIsActive = 'Y'
|
||||||
JOIN jurnal_tx
|
JOIN jurnal_tx
|
||||||
ON jurnalTxJurnalID = jurnalAddOnJurnalID
|
ON jurnalTxJurnalID = jurnalAddOnJurnalID
|
||||||
|
AND jurnalTxIsActive = 'Y'
|
||||||
AND jurnalTxCredit <> 0
|
AND jurnalTxCredit <> 0
|
||||||
AND jurnalTxCoaID <> 563
|
AND jurnalTxCoaID NOT IN ($notInPlaceholders)
|
||||||
LEFT JOIN supplier_payment
|
LEFT JOIN supplier_payment
|
||||||
ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID
|
ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID
|
||||||
AND SupplierInvoiceIsActive = 'Y'
|
AND SupplierInvoiceIsActive = 'Y'
|
||||||
@@ -152,7 +235,7 @@ class Bill extends MY_Controller
|
|||||||
AND SupplierPaymentDetailIsActive = 'Y'
|
AND SupplierPaymentDetailIsActive = 'Y'
|
||||||
WHERE SupplierInvoiceID = ?
|
WHERE SupplierInvoiceID = ?
|
||||||
GROUP BY jurnalTxID";
|
GROUP BY jurnalTxID";
|
||||||
$query = $this->db_onedev->query($sql, [$orderid]);
|
$query = $this->db_onedev->query($sql, array_merge($excludeIds, [$orderid]));
|
||||||
if ($query) {
|
if ($query) {
|
||||||
$rows = $query->result_array();
|
$rows = $query->result_array();
|
||||||
return $rows;
|
return $rows;
|
||||||
@@ -395,10 +478,19 @@ class Bill extends MY_Controller
|
|||||||
|
|
||||||
$dp_params = [$regionalid];
|
$dp_params = [$regionalid];
|
||||||
|
|
||||||
|
// ── INSTALLMENT branch WHERE ────────────────────────────
|
||||||
|
$inst_where = " inst.SupplierInstallmentIsActive = 'Y'
|
||||||
|
AND rop.ReceiveOrderPoS_RegionalID = ? ";
|
||||||
|
|
||||||
|
$inst_params = [$regionalid];
|
||||||
|
|
||||||
// ── UNION base ───────────────────────────────────────────
|
// ── UNION base ───────────────────────────────────────────
|
||||||
$sql_base = "
|
$sql_base = "
|
||||||
SELECT
|
SELECT
|
||||||
si.SupplierInvoiceID,
|
si.SupplierInvoiceID,
|
||||||
|
0 AS DownpaymentID,
|
||||||
|
0 AS InstallmentID,
|
||||||
|
0 AS parent_invoice_id,
|
||||||
si.SupplierInvoiceNumber,
|
si.SupplierInvoiceNumber,
|
||||||
si.SupplierInvoiceDraftPaymentDate,
|
si.SupplierInvoiceDraftPaymentDate,
|
||||||
si.SupplierInvoiceDraftPaymentDate AS filter_date,
|
si.SupplierInvoiceDraftPaymentDate AS filter_date,
|
||||||
@@ -441,7 +533,10 @@ class Bill extends MY_Controller
|
|||||||
UNION ALL
|
UNION ALL
|
||||||
|
|
||||||
SELECT
|
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,
|
CONCAT('DP-', po.PurchaseOrderNumber) AS SupplierInvoiceNumber,
|
||||||
dp.SupplierDownpaymentDueDate AS SupplierInvoiceDraftPaymentDate,
|
dp.SupplierDownpaymentDueDate AS SupplierInvoiceDraftPaymentDate,
|
||||||
dp.SupplierDownpaymentDueDate AS filter_date,
|
dp.SupplierDownpaymentDueDate AS filter_date,
|
||||||
@@ -480,7 +575,59 @@ class Bill extends MY_Controller
|
|||||||
ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID
|
ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID
|
||||||
JOIN purchase_order po
|
JOIN purchase_order po
|
||||||
ON po.PurchaseOrderID = dp.SupplierDownpaymentPurchasOrderID
|
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 common filters ─────────────────────────────────
|
||||||
$outer_where = " SupplierPaymentIsActive = 'Y'
|
$outer_where = " SupplierPaymentIsActive = 'Y'
|
||||||
@@ -506,7 +653,7 @@ class Bill extends MY_Controller
|
|||||||
FROM ($sql_base) AS combined
|
FROM ($sql_base) AS combined
|
||||||
WHERE $outer_where";
|
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);
|
$query = $this->db_onedev->query($sql_count, $count_params);
|
||||||
|
|
||||||
$tot_count = 0;
|
$tot_count = 0;
|
||||||
@@ -526,7 +673,7 @@ class Bill extends MY_Controller
|
|||||||
ORDER BY SupplierInvoiceID ASC
|
ORDER BY SupplierInvoiceID ASC
|
||||||
LIMIT ? OFFSET ?";
|
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);
|
$query = $this->db_onedev->query($sql_data, $data_params);
|
||||||
$rows = $query->result_array();
|
$rows = $query->result_array();
|
||||||
|
|
||||||
@@ -537,7 +684,7 @@ class Bill extends MY_Controller
|
|||||||
// ── Downpayment branch ──────────────────────────
|
// ── Downpayment branch ──────────────────────────
|
||||||
if ($v['type'] === 'DP') {
|
if ($v['type'] === 'DP') {
|
||||||
$rows[$k]['chex'] = false;
|
$rows[$k]['chex'] = false;
|
||||||
$dp_id = abs($v['SupplierInvoiceID']);
|
$dp_id = $v['DownpaymentID'];
|
||||||
|
|
||||||
$s_payment = $this->db_onedev->query("
|
$s_payment = $this->db_onedev->query("
|
||||||
SELECT
|
SELECT
|
||||||
@@ -566,6 +713,39 @@ class Bill extends MY_Controller
|
|||||||
continue;
|
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 ──────────────────────────────
|
// ── Invoice branch ──────────────────────────────
|
||||||
$rows[$k]['chex'] = false;
|
$rows[$k]['chex'] = false;
|
||||||
$inv_id = $v['SupplierInvoiceID'];
|
$inv_id = $v['SupplierInvoiceID'];
|
||||||
@@ -611,8 +791,8 @@ class Bill extends MY_Controller
|
|||||||
: "0.00";
|
: "0.00";
|
||||||
$rows[$k]['unpaid'] = number_format($unpaid, 2, '.', '');
|
$rows[$k]['unpaid'] = number_format($unpaid, 2, '.', '');
|
||||||
|
|
||||||
$rows[$k]['notes'] = $this->add_notes($inv_id);
|
$rows[$k]['notes'] = $this->add_notes($inv_id);
|
||||||
$rows[$k]['tagihans'] = $this->add_tagihans($inv_id);
|
$rows[$k]['tagihans'] = $this->add_tagihans($inv_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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)
|
public function add_tagihans($orderid)
|
||||||
{
|
{
|
||||||
$sql = "SELECT SupplierInvoiceID as tagihan_id,
|
$sql_dp = "SELECT
|
||||||
PurchaseOrderNumber as tagihan_number,
|
Fa_ClassDownPaymentCoaID
|
||||||
jurnalTxDescription as pasien,
|
FROM supplier_invoice_detail
|
||||||
jurnalTxCredit as tagihan_total,
|
JOIN m_item
|
||||||
IF(SupplierPaymentDetailID IS NULL , jurnalTxCredit, jurnalTxCredit - SUM(SupplierPaymentDetailAmount)) as tagihan_tagihan,
|
ON M_ItemID = SupplierInvoiceDetailItemID
|
||||||
0 as tagihan_bayar,
|
AND SupplierInvoiceDetailSupplierInvoiceID = ?
|
||||||
DATE_FORMAT(SupplierInvoiceDueDate,'%d-%m-%Y') as tagihan_duedate,
|
AND SupplierInvoiceDetailIsActive = 'Y'
|
||||||
SupplierInvoiceIsActive as tagihan_active,
|
AND SupplierInvoiceDetailIsVerified = 'Y'
|
||||||
'N' as show_detail,
|
JOIN fa_class
|
||||||
jurnalTxID SupplierInvoiceDetailID,
|
ON Fa_ClassID = M_ItemFa_ClassID
|
||||||
PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID
|
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
|
$notInPlaceholders = implode(',', array_fill(0, count($excludeIds), '?'));
|
||||||
JOIN receive_order_po ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
|
||||||
JOIN receive_order_po_detail ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID
|
$sql = "SELECT
|
||||||
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
SupplierInvoiceID as tagihan_id,
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
PurchaseOrderNumber as tagihan_number,
|
||||||
JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID AND jurnalTxCredit <> 0 AND jurnalTxCoaID <> 563
|
jurnalTxDescription as pasien,
|
||||||
LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierInvoiceIsActive = 'Y'
|
jurnalTxCredit as tagihan_total,
|
||||||
LEFT JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID AND SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID AND SupplierPaymentDetailIsActive = 'Y'
|
IF(SupplierPaymentDetailID IS NULL , jurnalTxCredit, jurnalTxCredit - SUM(SupplierPaymentDetailAmount)) as tagihan_tagihan,
|
||||||
WHERE
|
0 as tagihan_bayar,
|
||||||
SupplierInvoiceID = {$orderid}
|
DATE_FORMAT(SupplierInvoiceDueDate,'%d-%m-%Y') as tagihan_duedate,
|
||||||
GROUP BY jurnalTxID
|
SupplierInvoiceIsActive as tagihan_active,
|
||||||
";
|
'N' as show_detail,
|
||||||
$query = $this->db_onedev->query($sql);
|
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) {
|
if ($query) {
|
||||||
$rows = $query->result_array();
|
$rows = $query->result_array();
|
||||||
return $rows;
|
return $rows;
|
||||||
} else {
|
} else {
|
||||||
$this->sys_error_db("get notes", $this->db_onedev);
|
$this->sys_error_db("get tagihans", $this->db_onedev);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,7 +459,24 @@ class Bill extends MY_Controller
|
|||||||
$enddate,
|
$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 (
|
$sql_count = "SELECT SUM(cnt) as total FROM (
|
||||||
SELECT count(*) as cnt
|
SELECT count(*) as cnt
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
@@ -390,9 +495,24 @@ class Bill extends MY_Controller
|
|||||||
JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID
|
JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID
|
||||||
JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID
|
JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID
|
||||||
WHERE $dp_where
|
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";
|
) 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);
|
$query = $this->db_onedev->query($sql_count, $count_params);
|
||||||
|
|
||||||
$tot_count = 0;
|
$tot_count = 0;
|
||||||
@@ -410,6 +530,8 @@ class Bill extends MY_Controller
|
|||||||
SELECT * FROM (
|
SELECT * FROM (
|
||||||
SELECT
|
SELECT
|
||||||
SupplierInvoiceID,
|
SupplierInvoiceID,
|
||||||
|
0 as DownpaymentID,
|
||||||
|
0 as InstallmentID,
|
||||||
SupplierInvoiceNumber,
|
SupplierInvoiceNumber,
|
||||||
SupplierInvoiceDraftPaymentDate,
|
SupplierInvoiceDraftPaymentDate,
|
||||||
SupplierInvoiceIsLunas as flaglunas,
|
SupplierInvoiceIsLunas as flaglunas,
|
||||||
@@ -426,6 +548,7 @@ class Bill extends MY_Controller
|
|||||||
'' as SupplierPaymentDate,
|
'' as SupplierPaymentDate,
|
||||||
'' as notes,
|
'' as notes,
|
||||||
'' as tagihans,
|
'' as tagihans,
|
||||||
|
0 as parent_invoice_id,
|
||||||
'INVOICE' as type
|
'INVOICE' as type
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
@@ -440,14 +563,16 @@ class Bill extends MY_Controller
|
|||||||
UNION ALL
|
UNION ALL
|
||||||
|
|
||||||
SELECT
|
SELECT
|
||||||
SupplierDownpaymentID * -1 as SupplierInvoiceID,
|
0 as SupplierInvoiceID,
|
||||||
|
SupplierDownpaymentID as DownpaymentID,
|
||||||
|
0 as InstallmentID,
|
||||||
CONCAT('DP-', PurchaseOrderNumber) as SupplierInvoiceNumber,
|
CONCAT('DP-', PurchaseOrderNumber) as SupplierInvoiceNumber,
|
||||||
SupplierDownpaymentDueDate as SupplierInvoiceDraftPaymentDate,
|
SupplierDownpaymentDueDate as SupplierInvoiceDraftPaymentDate,
|
||||||
SupplierDownpaymentIsLunas as flaglunas,
|
SupplierDownpaymentIsLunas as flaglunas,
|
||||||
SupplierName,
|
SupplierName,
|
||||||
DATE_FORMAT(SupplierDownpaymentDueDate,'%d-%m-%Y') as tanggalbayar,
|
DATE_FORMAT(SupplierDownpaymentDueDate,'%d-%m-%Y') as tanggalbayar,
|
||||||
'N' as SupplierPaymentIsApproved,
|
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
||||||
'' as SupplierPaymentCashierNumber,
|
IFNULL(SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber,
|
||||||
SupplierDownpaymentAmount as totalbill,
|
SupplierDownpaymentAmount as totalbill,
|
||||||
CASE WHEN SupplierDownpaymentStatus = 'Paid'
|
CASE WHEN SupplierDownpaymentStatus = 'Paid'
|
||||||
THEN SupplierDownpaymentAmount
|
THEN SupplierDownpaymentAmount
|
||||||
@@ -461,17 +586,65 @@ class Bill extends MY_Controller
|
|||||||
'' as SupplierPaymentDate,
|
'' as SupplierPaymentDate,
|
||||||
'' as notes,
|
'' as notes,
|
||||||
'' as tagihans,
|
'' as tagihans,
|
||||||
|
0 as parent_invoice_id,
|
||||||
'DP' as type
|
'DP' as type
|
||||||
FROM supplier_downpayment
|
FROM supplier_downpayment
|
||||||
JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID
|
JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID
|
||||||
JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID
|
JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID
|
||||||
|
LEFT JOIN supplier_payment
|
||||||
|
ON SupplierPaymentSupplierDownpaymentID = SupplierDownpaymentID
|
||||||
|
AND SupplierPaymentIsActive = 'Y'
|
||||||
WHERE $dp_where
|
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
|
) AS combined
|
||||||
ORDER BY SupplierInvoiceID ASC
|
ORDER BY SupplierInvoiceID ASC
|
||||||
LIMIT ? OFFSET ?";
|
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);
|
$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();
|
$rows = $query->result_array();
|
||||||
|
|
||||||
// ── ENRICH — per-row sub-queries ───────────────────────────
|
// ── ENRICH — per-row sub-queries ───────────────────────────
|
||||||
@@ -480,7 +653,7 @@ class Bill extends MY_Controller
|
|||||||
|
|
||||||
// ── Downpayment branch ──────────────────────────
|
// ── Downpayment branch ──────────────────────────
|
||||||
if ($v['type'] === 'DP') {
|
if ($v['type'] === 'DP') {
|
||||||
$dp_id = abs($v['SupplierInvoiceID']);
|
$dp_id = $v['DownpaymentID'];
|
||||||
|
|
||||||
$s_payment = $this->db_onedev->query("
|
$s_payment = $this->db_onedev->query("
|
||||||
SELECT
|
SELECT
|
||||||
@@ -515,6 +688,44 @@ class Bill extends MY_Controller
|
|||||||
continue;
|
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 ───────────────────────────────
|
// ── Invoice branch ───────────────────────────────
|
||||||
$inv_id = $v['SupplierInvoiceID'];
|
$inv_id = $v['SupplierInvoiceID'];
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user