From e62ec1d99484d2e76167c05c5faa971e64587a8f Mon Sep 17 00:00:00 2001 From: sasadib Date: Fri, 10 Jul 2026 15:49:00 +0700 Subject: [PATCH] feature: file receiveItemAset & change some query purchaseorderasest --- .../purchase/order/PurchaseOrderAset.php | 144 +- .../receive-item-po/ReceiveItemPOAsset.php | 3258 +++++++++++++++++ 2 files changed, 3329 insertions(+), 73 deletions(-) create mode 100644 application/controllers/mockup/receive-item-po/ReceiveItemPOAsset.php diff --git a/application/controllers/mockup/purchase/order/PurchaseOrderAset.php b/application/controllers/mockup/purchase/order/PurchaseOrderAset.php index 5884b01..bb2ee73 100644 --- a/application/controllers/mockup/purchase/order/PurchaseOrderAset.php +++ b/application/controllers/mockup/purchase/order/PurchaseOrderAset.php @@ -81,59 +81,58 @@ class PurchaseOrderAset extends MY_Controller { } $limit = 10; - $offset = 0; - if ($para['currpage'] > 0) { - $offset = ($para['currpage'] - 1) * $limit; - } $sql = "SELECT - PurchaseRequestID, - PurchaseRequestNumber, - PurchaseRequestDetailID, - PurchaseRequestFlagID, - PurchaseRequestFlagM_BranchCode AS BranchCode, - PurchaseRequestItemCategoryID AS ItemCategoryID, - PurchaseRequestFlagQtyRest - PurchaseRequestFlagQtyProses AS UnprocessFlagQty, - PurchaseRequestDetailQty AS RequestQty, - PurchaseRequestDetailQty AS OriginalQty, - M_BranchName, - M_ItemID, - M_ItemCode, - M_ItemDesc, - ItemUnitID, - ItemUnitName, - SupplierPricePrice as SupplierPrice - FROM purchase_request - JOIN purchase_request_detail ON PurchaseRequestDetailPurchaseRequestID = PurchaseRequestID - AND PurchaseRequestDetailIsActive = 'Y' - AND PurchaseRequestM_BranchCode = ? - AND PurchaseRequestItemCategoryID = '3' -- id category item asset - AND PurchaseRequestNumber LIKE ? - JOIN purchase_request_flag ON PurchaseRequestFlagPurchaseRequestDetailID = PurchaseRequestDetailID - AND PurchaseRequestFlagStatus = 'PO' - AND PurchaseRequestFlagIsActive = 'Y' - JOIN m_item ON M_ItemID = PurchaseRequestDetailM_ItemID - JOIN itemunit ON ItemUnitID = PurchaseRequestDetailItemUnitID - JOIN supplier_price ON SupplierPriceSupplierID = ? - AND SupplierPriceM_ItemID = M_ItemID - AND SupplierPriceItemUnitID = ItemUnitID - AND SupplierPriceIsActive = 'Y' - JOIN m_branch ON M_BranchCode = PurchaseRequestFlagM_BranchCode - AND M_BranchIsActive = 'Y' - WHERE NOT EXISTS ( - SELECT 1 - FROM purchase_order_detail - JOIN purchase_order ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID - AND PurchaseOrderStatus = 'Approved' - AND PurchaseOrderIsActive = 'Y' - AND PurchaseOrderDetailIsActive = 'Y' - WHERE PurchaseOrderDetailPurchaseRequestDetailID = PurchaseRequestDetailID - )"; + PurchaseRequestID, + PurchaseRequestNumber, + PurchaseRequestDetailID, + PurchaseRequestFlagID, + M_BranchID, + PurchaseRequestFlagM_BranchCode AS BranchCode, + PurchaseRequestItemCategoryID AS ItemCategoryID, + PurchaseRequestFlagQtyRest - PurchaseRequestFlagQtyProses AS UnprocessFlagQty, + PurchaseRequestDetailQty AS RequestQty, + PurchaseRequestDetailQty AS OriginalQty, + M_BranchName, + M_ItemID, + M_ItemCode, + M_ItemDesc, + ItemUnitID, + ItemUnitName, + SupplierPricePrice as SupplierPrice, + M_UserUsername AS Requestedby + FROM purchase_request + JOIN purchase_request_detail ON PurchaseRequestDetailPurchaseRequestID = PurchaseRequestID + AND PurchaseRequestDetailIsActive = 'Y' + AND PurchaseRequestItemCategoryID = '3' -- id category item asset + JOIN m_item ON M_ItemID = PurchaseRequestDetailM_ItemID + AND (PurchaseRequestNumber LIKE ? OR M_ItemDesc LIKE ?) + JOIN purchase_request_flag ON PurchaseRequestFlagPurchaseRequestDetailID = PurchaseRequestDetailID + AND PurchaseRequestFlagStatus = 'PO' + AND PurchaseRequestFlagIsActive = 'Y' + JOIN m_branch ON M_BranchCode = PurchaseRequestFlagM_BranchCode + AND M_BranchID = ? + AND M_BranchIsActive = 'Y' + JOIN itemunit ON ItemUnitID = PurchaseRequestDetailItemUnitID + JOIN supplier_price ON SupplierPriceSupplierID = ? + AND SupplierPriceM_ItemID = M_ItemID + AND SupplierPriceItemUnitID = ItemUnitID + AND SupplierPriceIsActive = 'Y' + JOIN m_user ON M_UserID = PurchaseRequestRequestedBy + WHERE NOT EXISTS ( + SELECT 1 + FROM purchase_order_detail + JOIN purchase_order ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID + AND PurchaseOrderStatus = 'Approved' + AND PurchaseOrderIsActive = 'Y' + AND PurchaseOrderDetailIsActive = 'Y' + WHERE PurchaseOrderDetailPurchaseRequestDetailID = PurchaseRequestDetailID + )"; - $sql_data = $sql . " LIMIT ? OFFSET ? "; + $sql_data = $sql . " LIMIT ? "; $que_data = $this->db->query($sql_data, [ - $para['branchcode'], $keyword, $para['supplierID'], - $limit, $offset + $keyword, $keyword, $para['branchID'], $para['supplierID'], + $limit ]); if (!$que_data) { $this->sys_error_db("[Error] get daftar request data"); @@ -143,7 +142,7 @@ class PurchaseOrderAset extends MY_Controller { $sql_total = "SELECT COUNT(*) AS total FROM ($sql) AS x"; $que_total = $this->db->query($sql_total, [ - $para['branchcode'], $keyword, $para['supplierID'] + $keyword, $keyword, $para['branchID'], $para['supplierID'] ]); if (!$que_total) { $this->sys_error_db("[Error] get total request aset"); @@ -459,6 +458,28 @@ class PurchaseOrderAset extends MY_Controller { } } + public function getUserApproveLevel() { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $user = $this->sys_user; + $sql = "SELECT M_UserM_ApproveLevelID FROM m_user + WHERE M_UserIsActive = 'Y' AND M_UserID = ? "; + $que = $this->db->query($sql, [$user['M_UserID']]); + if (!$que) { + $this->sys_error_db("[Error] failed get approval level user"); + exit; + } + $data = $que->row_array(); + $this->sys_ok($data); + } catch (Exception $exc) { + $this->sys_error($exc->getMessage()); + } + } + ## MUTATIONS ## public function createPoAsset() { try { @@ -1027,7 +1048,6 @@ class PurchaseOrderAset extends MY_Controller { } } - // upload file public function uploadAttachment() { try { if (!$this->isLogin) { @@ -1166,28 +1186,6 @@ class PurchaseOrderAset extends MY_Controller { } } - public function getUserApproveLevel() { - try { - if (!$this->isLogin) { - $this->sys_error("invalid token"); - exit; - } - - $user = $this->sys_user; - $sql = "SELECT M_UserM_ApproveLevelID FROM m_user - WHERE M_UserIsActive = 'Y' AND M_UserID = ? "; - $que = $this->db->query($sql, [$user['M_UserID']]); - if (!$que) { - $this->sys_error_db("[Error] failed get approval level user"); - exit; - } - $data = $que->row_array(); - $this->sys_ok($data); - } catch (Exception $exc) { - $this->sys_error($exc->getMessage()); - } - } - private function insertLog($poID, $type, $prm, $dataBefore, $dataAfter, $userID, $desc = '') { $sql = "INSERT INTO acc_one_log.purchase_order_log ( PurchaseOrderLogPurchaseOrderID, diff --git a/application/controllers/mockup/receive-item-po/ReceiveItemPOAsset.php b/application/controllers/mockup/receive-item-po/ReceiveItemPOAsset.php new file mode 100644 index 0000000..b4115fb --- /dev/null +++ b/application/controllers/mockup/receive-item-po/ReceiveItemPOAsset.php @@ -0,0 +1,3258 @@ +isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $payload = $this->sys_input; + $search = $payload['search'] . '%'; + + $sql = "SELECT + SupplierID, + SupplierCode, + SupplierName + FROM supplier + WHERE SupplierIsActive = 'Y' + AND SupplierName LIKE ? + ORDER BY SupplierName ASC "; + $que = $this->db->query($sql, [$search]); + if (!$que) { + $this->sys_error_db("[Error] query listing supplier");; + exit; + } + + $data = $que->result_array(); + $this->sys_ok($data); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function getRuangan() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $payload = $this->sys_input; + $user = $this->sys_user; + $search = $payload['search'] . '%'; + + $sql = "SELECT M_RuanganID, + M_RuanganM_BranchID, + M_RuanganName, + M_RuanganCode + FROM m_ruangan + WHERE M_RuanganIsActive = 'Y' + AND M_RuanganM_BranchID = ? + AND M_RuanganName LIKE ? + ORDER BY M_RuanganName ASC"; + $qry = $this->db->query($sql, [$user['M_BranchID'], $search]); + + if (!$qry) { + $this->sys_error_db("[Error] query listing ruangan");; + exit; + } + + $data = $qry->result_array(); + $this->sys_ok($data); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function getInventarisBelumSerah() + { + try { + if (!$this->isLogin) { + throw new Exception('invalid token'); + } + + $para = $this->sys_input; + + $sql = "SELECT + rod.ReceiveOrderPoDetailID, + rod.ReceiveOrderPoItemID, + rod.ReceiveOrderPoItemUnitID, + mi.M_ItemDesc, + rod.ReceiveOrderPoDetailQty AS originalQty, + COALESCE(ahd_count.InsertedQty, 0) AS serahQty, + rod.ReceiveOrderPoDetailQty - COALESCE(ahd_count.InsertedQty, 0) AS sisaQty, + CASE + WHEN COALESCE(ahd_count.InsertedQty, 0) = rod.ReceiveOrderPoDetailQty THEN 'Y' + ELSE 'N' + END AS isHandoverDone + FROM receive_order_po_detail rod + JOIN m_item mi ON mi.M_ItemID = rod.ReceiveOrderPoItemID + LEFT JOIN ( + SELECT + AssetHandoverDetailReceiveOrderPoDetailID, + COUNT(*) AS InsertedQty + FROM asset_handover_detail ahd + JOIN asset_handover ah ON ahd.AssetHandoverDetailAssetHandoverID = ah.AssetHandoverID + AND ah.AssetHandoverIsActive = 'Y' + WHERE ahd.AssetHandoverDetailIsActive = 'Y' + AND ah.AssetHandoverReceiveOrderPoID = ? + GROUP BY AssetHandoverDetailReceiveOrderPoDetailID + ) ahd_count ON ahd_count.AssetHandoverDetailReceiveOrderPoDetailID = rod.ReceiveOrderPoDetailID + WHERE rod.ReceiveOrderPoDetailReceiveOrderPoID = ? + AND rod.ReceiveOrderPoDetailIsActive = 'Y'"; + $que = $this->db->query($sql, [$para['ROID'], $para['ROID']]); + if (!$que) { + throw new Exception('listing inventory belum yg diserah terima', 1); + } + $data = $que->result_array(); + + $this->sys_ok($data); + } catch (Exception $e) { + $message = $e->getMessage(); + $code = $e->getCode(); + if ($code == 1) { + $this->sys_error_db("[Error] " . $message); + } else { + $this->sys_error("[Error] " . $message); + } + exit; + } + } + + function getPurchaseOrder() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $payload = $this->sys_input; + $user = $this->sys_user; + + $const_params = [ + $user['M_BranchID'] ?? 0, + $user['S_RegionalID'], + $payload['SupplierID'], + $payload['search'] . '%' + ]; + + $placeholders = '?'; + $list_includeID = ["0"]; + $localPO_deleted = $payload['localPO_deleted']; + if (sizeof($localPO_deleted) > 0) { + $placeholders = implode(", ", array_fill(0, count($localPO_deleted), '?')); + $list_includeID = $payload['localPO_deleted']; + } + + $params = array_merge($list_includeID, $const_params); + + $sql = "SELECT + GROUP_CONCAT(DISTINCT PurchaseOrderDetailWarehouseID) AS arrWarehouse, + purchase_order.* + FROM purchase_order + JOIN purchase_order_detail ON PurchaseOrderID = PurchaseOrderDetailPurchaseOrderID + AND PurchaseOrderDetailIsActive = 'Y' + AND + ((SELECT IFNULL(SUM(PoItemReceiveQty - PoItemReceiveQtyReceived), 0) + FROM po_item_receive + WHERE PoItemReceivePurchaseOrderID = PurchaseOrderID) > 0) + OR + (SELECT PoItemReceiveID + FROM po_item_receive + WHERE PoItemReceivePurchaseOrderID = PurchaseOrderID + AND PoItemReceiveID IN ({$placeholders})) + JOIN warehouse ON PurchaseOrderDetailWarehouseID = WarehouseID + AND WarehouseM_BranchID = ? + WHERE WarehouseS_RegionalID = ? + AND PurchaseOrderSupplierID = ? + AND PurchaseOrderStatus = 'Approved' + AND PurchaseOrderItemCategoryID = 3 + AND PurchaseOrderNumber LIKE ? + AND PurchaseOrderIsActive = 'Y' + GROUP BY PurchaseOrderID + ORDER BY PurchaseOrderID DESC LIMIT 50"; + $que = $this->db->query($sql, $params); + if (!$que) { + $this->sys_error_db("[Error] query purhcase order"); + exit; + } + $data = $que->result_array(); + $this->sys_ok($data); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function getWarehouse() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $user = $this->sys_user; + $whtype = ($user['M_UserLocationFlag'] == 'R') ? 'R' : 'B'; + + $sql = "SELECT + WarehouseID, + WarehouseCode, + CASE + WHEN WarehouseType = 'B' THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName) + WHEN WarehouseType = 'R' THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName) + ELSE '' + END WarehouseName, + WarehouseType, + WarehouseIsDefault, + WarehouseS_RegionalID, + WarehouseM_BranchID, + S_RegionalID, + S_RegionalName + FROM warehouse + JOIN s_regional ON WarehouseS_RegionalID = S_RegionalID AND S_RegionalIsActive = 'Y' + LEFT JOIN m_branch ON WarehouseM_BranchID = M_BranchID AND M_BranchIsActive = 'Y' + WHERE WarehouseS_RegionalID = ? + AND WarehouseIsActive = 'Y' AND WarehouseIsTransit = 'N' + AND WarehouseType = ? AND WarehouseM_BranchID = ? + ORDER BY WarehouseName ASC"; + $que = $this->db->query($sql, [ + $user['S_RegionalID'], + $whtype, + $user['M_BranchID'] + ]); + if (!$que) { + $this->sys_error_db("[Error] get list warehouse"); + exit; + } + $data = $que->result_array(); + $this->sys_ok($data); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function getItem() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $param = $this->sys_input; + $user = $this->sys_user; + + $POID = $param['POID']; + $warehouseID = $param['WarehouseID']; + + $sql = "SELECT + CONCAT(PoItemReceiveID,',','-') as keyID, + PoItemReceiveID, + PurchaseOrderNumber, + PurchaseOrderShippingCost, + PurchaseOrderShippingCostStatus, + PoItemReceivePurchaseOrderID, + PoItemReceivePurchaseOrderSummaryID, + PoItemReceivePurchaseOrderDetailID, + WarehouseID, + WarehouseCode, + CASE + WHEN WarehouseType = 'B' + THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName) + WHEN WarehouseType = 'R' + THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName) + ELSE '' + END WarehouseName, + M_ItemID, + M_ItemCode, + M_ItemDesc, + ItemUnitID, + ItemUnitName, + M_ItemItem_CategoryID, + PoItemReceiveQty as originalQty, + PoItemReceiveQtyReceived as receivedQty, + 0 as qty, + PoItemReceiveQty - PoItemReceiveQtyReceived AS qtyRest, + PoItemReceivePrice, + 'N' as alreadySave + FROM po_item_receive + JOIN purchase_order ON PoItemReceivePurchaseOrderID = PurchaseOrderID + AND PurchaseOrderIsActive = 'Y' + AND PoItemReceiveIsActive = 'Y' + JOIN warehouse ON PoItemReceiveWarehouseID = WarehouseID + AND WarehouseIsActive = 'Y' + JOIN m_item ON PoItemReceiveItemID = M_ItemID + JOIN itemunit ON PoItemReceiveItemUnitID= ItemUnitID + JOIN s_regional ON WarehouseS_RegionalID = S_RegionalID + LEFT JOIN m_branch ON WarehouseM_BranchID = M_BranchID + WHERE PurchaseOrderID = ? AND WarehouseID = ?"; + $que = $this->db->query($sql, [$POID, $warehouseID]); + if (!$que) { + $this->sys_error_db("[Error] ger item PO");; + exit; + } + $data = $que->result_array(); + foreach ($data as $key => $value) { + $data[$key]['batchlist'] = []; + } + + $this->sys_ok($data); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function getItemUpdate() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $param = $this->sys_input; + $ROID = $param['ROID']; + + $sql = "SELECT + ReceiveOrderPoDetailID, + CONCAT(ReceiveOrderPoDetailPoItemReceiveID,',',ReceiveOrderPoDetailID) AS keyID, + ReceiveOrderPoDetailPoItemReceiveID AS PoItemReceiveID, + PurchaseOrderNumber, + PurchaseOrderShippingCost, + PurchaseOrderShippingCostStatus, + ReceiveOrderPoDetailPurchaseOrderID AS PoItemReceivePurchaseOrderID, + ReceiveOrderPoDetailPurchaseOrderSummaryID AS PoItemReceivePurchaseOrderSummaryID, + ReceiveOrderPoDetailPurchaseOrderDetailID AS PoItemReceivePurchaseOrderDetailID, + WarehouseID, + WarehouseCode, + CASE + WHEN WarehouseType = 'B' + THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName) + WHEN WarehouseType = 'R' + THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName) + ELSE '' + END WarehouseName, + M_RuanganID, + M_RuanganName, + M_RuanganCode, + M_ItemID, + M_ItemCode, + M_ItemDesc, + ItemUnitID, + ItemUnitName, + M_ItemItem_CategoryID, + PoItemReceiveQty AS originalQty, + PoItemReceiveQtyReceived AS receivedQty, + ReceiveOrderPoDetailQty AS qty, + ReceiveOrderPoDetailQty AS tmpQty, + PoItemReceiveQty - PurchaseOrderSummaryQtyReceived AS qtyRest, + ReceiveOrderPoDetailQty, + PoItemReceivePrice, + 'Y' AS alreadySave, + ReceiveOrderPoDetailBatchNo AS batchNo, + ReceiveOrderPoDetailEd AS itemEd, + ReceiveOrderPoDetailBatchList + FROM receive_order_po_detail + JOIN receive_order_po ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID + JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID + JOIN po_item_receive ON ReceiveOrderPoDetailPoItemReceiveID = PoItemReceiveID + JOIN purchase_order_summary ON PurchaseOrderSummaryID = PoItemReceivePurchaseOrderSummaryID + JOIN warehouse ON ReceiveOrderPoWarehouseID = WarehouseID + JOIN m_item ON ReceiveOrderPoItemID = M_ItemID + JOIN itemunit ON ReceiveOrderPoItemUnitID = ItemUnitID + JOIN s_regional ON WarehouseS_RegionalID = S_RegionalID + LEFT JOIN m_branch ON WarehouseM_BranchID = M_BranchID + LEFT JOIN m_ruangan ON M_RuanganM_BranchID = M_BranchID + WHERE ReceiveOrderPoDetailIsActive = 'Y' + AND ReceiveOrderPoDetailReceiveOrderPoID = ? + ORDER BY ReceiveOrderPoDetailID ASC"; + $que = $this->db->query($sql, [$ROID]); + if (!$que) { + $this->sys_error_db("[Error] get item untuk update"); + exit; + } + + $data = $que->result_array(); + + foreach ($data as $key => $item) { + $jsonstr = $item['ReceiveOrderPoDetailBatchList']; + $batchlist = []; + + if (!empty($jsonstr)) { + $decode = json_decode($jsonstr); + if ($decode !== null && json_last_error() === JSON_ERROR_NONE) { + $batchlist = $decode; + } else { + $this->sys_error("[Error] decode json batch list item received"); + exit; + } + $data[$key]['batchlist'] = $batchlist; + unset($data[$key]['ReceiveOrderPoDetailBatchList']); + } + } + + $detailID = array_column($data, 'ReceiveOrderPoDetailID'); + $placeholders = implode(", ", array_fill(0, count($detailID), '?')); + + $sqlInspeksi = "SELECT + ReceiveOrderPoInspeksiID, + ReceiveOrderPoInspeksiReceiveOrderPoDetailID, + ReceiveOrderPoInspeksiQtyPesan AS qty_po, + ReceiveOrderPoInspeksiQtyActual AS qty_ro, + ReceiveOrderPoInspeksiPricePesan AS price_po, + ReceiveOrderPoInspeksiPriceActual AS price_ro, + ReceiveOrderPoInspeksiDatePesan AS date_po, + ReceiveOrderPoInspeksiDateActual AS date_ro, + ReceiveOrderPoInspeksiExpireDate AS expire_date, + ReceiveOrderPoInspeksiKeadaanKemasan AS condt_kemasan, + ReceiveOrderPoInspeksiKeadaanKemasanNote AS catatan_kemasan, + ReceiveOrderPoInspeksiKondisiPengiriman AS condt_pengiriman, + ReceiveOrderPoInspeksiKondisiPengirimanNote AS catatan_kirim, + ReceiveOrderPoInspeksiSimpulan AS summary, + ReceiveOrderPoInspeksiCatatan AS catatan, + ReceiveOrderPoInspeksiStaffPenerimaID AS pemeriksa, + ReceiveOrderPoInspeksiPengirim AS pengirim + FROM receive_order_po_inspeksi + WHERE ReceiveOrderPoInspeksiIsActive = 'Y' + AND ReceiveOrderPoInspeksiReceiveOrderPoDetailID IN ({$placeholders})"; + $queInspeksi = $this->db->query($sqlInspeksi, $detailID); + if (!$queInspeksi) { + $this->sys_error_db("[Error] get item inspeksi data"); + exit; + } + $list_inspeksi = $queInspeksi->result_array(); + + $lookup_map = []; + foreach ($list_inspeksi as $inspeksi) { + $RODetailID = $inspeksi['ReceiveOrderPoInspeksiReceiveOrderPoDetailID']; + $lookup_map[$RODetailID] = $inspeksi; + } + + $sql_barcode = "SELECT T_BarcodeBarangID, + T_BarcodeBarangReceiveOrderPoDetailID, + T_BarcodeBarangM_ItemID + FROM t_barcode_barang + WHERE T_BarcodeBarangIsActive = 'Y' + AND T_BarcodeBarangReceiveOrderPoDetailID IN ($placeholders)"; + $qry_barcode = $this->db->query($sql_barcode, $detailID); + if (!$qry_barcode) { + $this->sys_error_db("[Error] get item barcode data"); + exit; + } + $list_barcode = $qry_barcode->result_array(); + + $lookup_map_barcode = []; + foreach ($list_barcode as $barcode) { + $RODetailID = $barcode['T_BarcodeBarangReceiveOrderPoDetailID']; + $lookup_map_barcode[$RODetailID][] = $barcode; + } + + $result = []; + foreach ($data as $rodetail) { + $rodetailID = $rodetail['ReceiveOrderPoDetailID']; + + // gabung inspeksi + if (isset($lookup_map[$rodetailID])) { + $rodetail['inspeksi_item'] = $lookup_map[$rodetailID]; + } + + // gabung barcode + if (isset($lookup_map_barcode[$rodetailID])) { + $rodetail['barcode_item'] = $lookup_map_barcode[$rodetailID]; + } + + $result[] = $rodetail; + } + + $this->sys_ok($result); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function searchRO() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $param = $this->sys_input; + $user = $this->sys_user; + + $search = $param['search'] . '%'; + $startdate = $param['startdate']; + $enddate = $param['enddate']; + $regID = $user['S_RegionalID']; + $brnCD = $user['M_BranchCode'] . '%'; + + $page = 0; + $limit = 15; + if ($param['page'] > 0) { + $page = ($param['page'] - 1) * $limit; + } + + $sql = "SELECT + ReceiveOrderPoNumber, + ReceiveOrderPoID, + ReceiveOrderPoSupplierID, + ReceiveOrderPoIDate, + ReceiveOrderShippingCostAmount, + ReceiveOrderPoNote, + ReceiveOrderPoRefNumber, + ReceiveOrderPoDONumber, + ReceiveOrderPoIsHandover, + SupplierID, + SupplierName, + WarehouseID, + WarehouseCode, + CASE + WHEN WarehouseType = 'B' + THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName) + WHEN WarehouseType = 'R' + THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName) + ELSE '' + END WarehouseName, + ReceiveOrderPoConfirmed, + DATE_FORMAT(ReceiveOrderPoConfirmedDate, '%d-%m-%Y %H:%i') AS ReceiveOrderPoConfirmedDate, + M_UserUsername AS ReceiveOrderPoConfirmedUserName + FROM receive_order_po + JOIN warehouse ON ReceiveOrderPoWarehouseID = WarehouseID + JOIN supplier ON ReceiveOrderPoSupplierID = SupplierID + JOIN s_regional ON WarehouseS_RegionalID = S_RegionalID + AND S_RegionalIsActive = 'Y' + LEFT JOIN m_branch ON WarehouseM_BranchID = M_BranchID + AND M_BranchIsActive = 'Y' + LEFT JOIN m_user ON ReceiveOrderPoConfirmedUserID = M_UserID + WHERE ReceiveOrderPoIsActive = 'Y' + AND (ReceiveOrderPoNumber LIKE ? OR ReceiveOrderPoDONumber LIKE ?) + AND ReceiveOrderPoIDate BETWEEN DATE(?) AND DATE(?) + AND ReceiveOrderPoS_RegionalID = ? + AND ReceiveOrderPoM_BranchCode LIKE ? + AND ReceiveOrderPoID NOT IN ( + SELECT DISTINCT ReceiveOrderPoDetailReceiveOrderPoID + FROM receive_order_po_detail + JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID + WHERE PurchaseOrderItemCategoryID IN (1,2,4) + AND ReceiveOrderPoDetailIsActive = 'Y' + ) + ORDER BY ReceiveOrderPoID DESC"; + + $sqltotal = "SELECT COUNT(*) as total FROM ($sql) as x"; + $quetotal = $this->db->query($sqltotal, [$search, $search, $startdate, $enddate, $regID, $brnCD]); + if (!$quetotal) { + $this->sys_error_db("[Error] get total data RO"); + exit; + } + $total = $quetotal->row_array()['total']; + + $sqldata = $sql . " LIMIT ? OFFSET ?"; + $quedata = $this->db->query($sqldata, [ + $search, + $search, + $startdate, + $enddate, + $regID, + $brnCD, + $limit, + $page + ]); + if (!$quedata) { + $this->sys_error_db("[Error] get list data RO"); + exit; + } + + $records = $quedata->result_array(); + foreach ($records as $key => $value) { + $sql = "SELECT + ReceiveOrderPoDocumentID, + ReceiveOrderPoDocumentDate, + ReceiveOrderPoDocumentFile + FROM receive_order_po_document + WHERE ReceiveOrderPoDocumentIsActive = 'Y' + AND ReceiveOrderPoDocumentReceiveOrderPoID = ?"; + $qry = $this->db->query($sql, [$value['ReceiveOrderPoID']]); + if (!$qry) { + $this->sys_error_db("[Error] get document RO"); + exit; + } + + $rowsdata = $qry->result_array(); + if (count($rowsdata) > 0) { + $records[$key]['hasDocuments'] = true; + $records[$key]['documents'] = $rowsdata; + } else { + $records[$key]['hasDocuments'] = false; + $records[$key]['documents'] = []; + } + } + + $result = array( + "records" => $records, + "total" => ceil($total / $limit) + ); + $this->sys_ok($result); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function getItemDataInspeksi() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $param = $this->sys_input; + $RODetailID = $param['RODetailID']; + + $sql = "SELECT + ReceiveOrderPoInspeksiID, + ReceiveOrderPoInspeksiReceiveOrderPoDetailID, + ReceiveOrderPoInspeksiQtyPesan, + ReceiveOrderPoInspeksiQtyActual, + ReceiveOrderPoInspeksiPricePesan, + ReceiveOrderPoInspeksiPriceActual, + ReceiveOrderPoInspeksiDatePesan, + ReceiveOrderPoInspeksiDateActual, + ReceiveOrderPoInspeksiExpireDate, + ReceiveOrderPoInspeksiKeadaanKemasan, + ReceiveOrderPoInspeksiKondisiPengiriman, + ReceiveOrderPoInspeksiSimpulan, + ReceiveOrderPoInspeksiCatatan, + ReceiveOrderPoInspeksiStaffPenerima, + ReceiveOrderPoInspeksiStaffPengirim + FROM receive_order_po_inspeksi + WHERE ReceiveOrderPoInspeksiIsActive = 'Y' + AND ReceiveOrderPoInspeksiReceiveOrderPoDetailID = ?"; + $que = $this->db->query($sql, [$RODetailID]); + if (!$que) { + $this->sys_error_db("[Error] get data inspeksi item"); + exit; + } + $data = $que->row_array(); + + $this->sys_ok($data); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function getListStaff() + { + try { + if (!$this->isLogin) { + $this->sys_error("Invalid token"); + exit; + } + + $user = $this->sys_user; + $param = $this->sys_input; + + if ($param['isSerahTerima'] == 'Y') { + $sql = "SELECT DISTINCT + u.M_UserID, + u.M_UserUsername + FROM receive_order_po ro + JOIN receive_order_po_detail rod ON rod.ReceiveOrderPoDetailReceiveOrderPoID = ro.ReceiveOrderPoID + AND rod.ReceiveOrderPoDetailIsActive = 'Y' + JOIN purchase_order_detail pod ON pod.PurchaseOrderDetailID = rod.ReceiveOrderPoDetailPurchaseOrderDetailID + AND pod.PurchaseOrderDetailIsActive = 'Y' + JOIN purchase_request pr ON pr.PurchaseRequestID = pod.PurchaseOrderDetailPurchaseRequestID + AND pr.PurchaseRequestIsActive = 'Y' + JOIN m_user u ON u.M_UserID = pr.PurchaseRequestRequestedBy + AND u.M_UserIsActive = 'Y' + WHERE ro.ReceiveOrderPoID = ? + AND ro.ReceiveOrderPoIsActive = 'Y'"; + $que = $this->db->query($sql, [$param['ROID']]); + } else { + $sql = "SELECT + M_UserID, + M_UserUsername + FROM m_user + WHERE M_UserM_BranchID = ? + AND M_UserS_RegionalID = ? + AND M_UserIsActive = 'Y' + ORDER BY M_UserUsername"; + $que = $this->db->query($sql, [$user['M_BranchID'], $user['S_RegionalID']]); + } + + if (!$que) { + $this->sys_error_db("[Error] get staff"); + exit; + } + $data = $que->result_array(); + $this->sys_ok($data); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + private function generateNoLogistik($user, $typeLogistik): string + { + $areaid = ($user['loginLevel'] == 'regional') ? $user['S_RegionalID'] : $user['M_BranchID']; + $areatype = ($user['loginLevel'] == 'regional') ? 'R' : 'B'; + + $sqlusrdivisi = "SELECT M_UserDivisionDivisionID FROM m_userdivision + WHERE M_UserDivisionM_UserID = ? AND M_UserDivisionIsActive = 'Y'"; + $queusrdivisi = $this->db->query($sqlusrdivisi, [$user['M_UserID']]); + if (!$queusrdivisi) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get user divisi"); + exit; + } + + $usrdivisiID = $queusrdivisi->row_array()['M_UserDivisionDivisionID']; + if (!isset($usrdivisiID)) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] user divisi id null"); + exit; + } + + $sqlnum = "SELECT `fn_penomoran`(?, ?, ?, ?, ?, ?) AS numpd;"; + $quenum = $this->db->query($sqlnum, [$typeLogistik, $usrdivisiID, $areatype, $areaid, 'SM', 'Y']); + if (!$quenum) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] generate number PI"); + exit; + } + + $numPL = $quenum->row_array()['numpd']; + if (!isset($numPL)) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] number PI null"); + exit; + } + + return $numPL; + } + + private function generateNoBarcode($user, $lokasiID, $typeBarcode, $itemid) + { + $branchid = ($user['loginLevel'] == 'branch') ? $user['M_BranchID'] : 0; + + if ($user['loginlevel'] == 'regional') { + $this->db->trans_rollback(); + $this->sys_error('Tidak bisa generare No Barcode, anda login sebagai regional'); + exit; + } + + // -- numtype = tipe numbering + // -- itemid = id item inventaris/asset + // -- branchid = id cabang + // -- ruanganid = id ruangan di cabang + + $sqlnum = "SELECT `fn_num_nonpersediaan`(?, ?, ?, ?) AS numpd;"; + $quenum = $this->db->query($sqlnum, [$typeBarcode, $itemid, $branchid, $lokasiID]); + + if (!$quenum) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] generate number Barcode"); + exit; + } + + $numPL = $quenum->row_array()['numpd']; + if (!isset($numPL)) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] number Barcode null"); + exit; + } + + return $numPL; + } + + private function getPOItemReceived($id) + { + $sql = "SELECT * FROM po_item_receive + JOIN warehouse ON PoItemReceiveWarehouseID= WarehouseID + JOIN itemunit ON PoItemReceiveItemUnitID = ItemUnitID + WHERE PoItemReceiveID = ?"; + $que = $this->db->query($sql, [$id]); + if (!$que) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] getDataPoItemReceive");; + exit; + } + return $que->row_array(); + } + + private function getDataROPO($id) + { + $sql = "SELECT * FROM receive_order_po WHERE ReceiveOrderPoID = ?"; + $que = $this->db->query($sql, [$id]); + if (!$que) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] getDataReceiveOrderPO ");; + exit; + } + $ROheader = $que->row_array(); + + $sqldetail = "SELECT * FROM receive_order_po_detail + WHERE ReceiveOrderPoDetailReceiveOrderPoID = ? AND ReceiveOrderPoDetailIsActive = 'Y'"; + $quedetail = $this->db->query($sqldetail, [$id]); + if (!$quedetail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] getDataReceiveOrderPO detail");; + exit; + } + $ROdetail = $quedetail->result_array(); + $ROheader['details'] = $ROdetail; + return $ROheader; + } + + ## MUTATION ## + + function saveRO() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $this->db->trans_begin(); + $param = $this->sys_input; + $user = $this->sys_user; + + # generate nomor purchase invoice # + $numGR = $this->generateNoLogistik($user, 'GR'); + + # insert table ro # + $sqlInsRO = "INSERT INTO receive_order_po ( + ReceiveOrderPoNumber, + ReceiveOrderPoSupplierID, + ReceiveOrderPoIDate, + ReceiveOrderPoWarehouseID, + ReceiveOrderPoM_BranchCode, + ReceiveOrderPoS_RegionalID, + ReceiveOrderShippingCostAmount, + ReceiveOrderShippingCostIsPaid, + ReceiveOrderPoNote, + ReceiveOrderPoRefNumber, + ReceiveOrderPoDONumber, + ReceiveOrderPoCreatedUserID + ) VALUE (?,?,?,?,?,?,?,?,?,?,?,?)"; + $queInsRO = $this->db->query($sqlInsRO, [ + $numGR, + $param['supplierID'], + $param['date'], + $param['warehouseID'], + $user['M_BranchCode'], + $user['S_RegionalID'], + $param['shippingCost'], + $param['shippingIsPaid'], + $param['note'], + $param['refNumber'], + $param['refNumber'], + $user['M_UserID'] + ]); + if (!$queInsRO) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert into table receive order po"); + exit; + } + $roID = $this->db->insert_id(); + + # inset to table ro detail # + $logDesc = []; + foreach ($param['detail'] as $key => $obj) { + $sqlRcvdItem = "SELECT * FROM po_item_receive WHERE PoItemReceiveID = ?"; + $queRcvdItem = $this->db->query($sqlRcvdItem, [$obj['PoItemReceiveID']]); + if (!$queRcvdItem) { + $this->db->trans_rollback(); + $this->sys_error_db("Error cek data item po_item_receive"); + exit; + } + $cekReceived = $queRcvdItem->row_array(); + + # cek item received # + if ($cekReceived['PoItemReceiveIsActive'] == 'N') { + $this->db->trans_rollback(); + $this->sys_error("[Error] Item {$obj['M_ItemDesc']} sudah diterima"); + exit; + } + + if ($cekReceived['PoItemReceiveQtyReceived'] == $cekReceived['PoItemReceiveQty']) { + $this->db->trans_rollback(); + $this->sys_error("[Error] Item {$obj['M_ItemDesc']} sudah diterima semuanya"); + exit; + } + + if (intval($obj['qty']) > intval($cekReceived['PoItemReceiveQty'])) { + $this->db->trans_rollback(); + $this->sys_error("Jumlah item {$obj['M_ItemDesc']} yang tersedia sudah berubah silahkan ulangi pilih item"); + exit; + } + + $jsonBatch = "[]"; + if (isset($obj['batchlist']) && is_array($obj['batchlist'])) { + $batchlist = $obj['batchlist']; + if (sizeof($batchlist) > 0) { + $json = json_encode($batchlist); + if ($json === false) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] encode json batch number"); + exit; + } else { + $jsonBatch = $json; + } + } + } + + $sqlInsRODetail = "INSERT INTO receive_order_po_detail ( + ReceiveOrderPoDetailReceiveOrderPoID, + ReceiveOrderPoDetailPurchaseOrderID, + ReceiveOrderPoDetailPurchaseOrderSummaryID, + ReceiveOrderPoDetailPurchaseOrderDetailID, + ReceiveOrderPoDetailPoItemReceiveID, + ReceiveOrderPoDetailQty, + ReceiveOrderPoDetailPrice, + ReceiveOrderPoDetailTotal, + ReceiveOrderPoDetailCreatedUserID, + ReceiveOrderPoItemID, + ReceiveOrderPoItemUnitID, + ReceiveOrderPoDetailBatchNo, + ReceiveOrderPoDetailEd, + ReceiveOrderPoDetailBatchList + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $queInsRODetail = $this->db->query($sqlInsRODetail, [ + $roID, + $obj['PoItemReceivePurchaseOrderID'], + $obj['PoItemReceivePurchaseOrderSummaryID'], + $obj['PoItemReceivePurchaseOrderDetailID'], + $obj['PoItemReceiveID'], + $obj['qty'], + $obj['PoItemReceivePrice'], + (doubleval($obj['PoItemReceivePrice']) * intval($obj['qty'])), + $user['M_UserID'], + $obj['M_ItemID'], + $obj['ItemUnitID'], + $obj['batchNo'], + $obj['itemEd'], + $jsonBatch + ]); + if (!$queInsRODetail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] receive order detail"); + exit; + } + + $logDesc[] = "- ADD {$obj['M_ItemDesc']} {$obj['qty']} {$obj['ItemUnitName']} nomor batch {$obj['WarehouseName']}"; + + $RODetailID = $this->db->insert_id(); + + # INSERT INTO receive_order_po_inspeksi # + $inspeksi = $obj['inspeksi_item']; + $sqlInspeksi = "INSERT INTO receive_order_po_inspeksi ( + ReceiveOrderPoInspeksiReceiveOrderPoDetailID, + ReceiveOrderPoInspeksiQtyPesan, + ReceiveOrderPoInspeksiQtyActual, + ReceiveOrderPoInspeksiPricePesan, + ReceiveOrderPoInspeksiPriceActual, + ReceiveOrderPoInspeksiDatePesan, + ReceiveOrderPoInspeksiDateActual, + ReceiveOrderPoInspeksiKeadaanKemasan, + ReceiveOrderPoInspeksiKeadaanKemasanNote, + ReceiveOrderPoInspeksiKondisiPengiriman, + ReceiveOrderPoInspeksiKondisiPengirimanNote, + ReceiveOrderPoInspeksiSimpulan, + ReceiveOrderPoInspeksiCatatan, + ReceiveOrderPoInspeksiStaffPenerimaID, + ReceiveOrderPoInspeksiPengirim, + ReceiveOrderPoInspeksiUserID + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $queInspeksi = $this->db->query($sqlInspeksi, [ + $RODetailID, + $inspeksi['qty_po'], + $inspeksi['qty_ro'], + $inspeksi['price_po'], + $inspeksi['price_ro'], + $inspeksi['date_po'], + $inspeksi['date_ro'], + $inspeksi['condt_kemasan'], + $inspeksi['catatan_kemasan'], + $inspeksi['condt_pengiriman'], + $inspeksi['catatan_kirim'], + $inspeksi['summary'], + $inspeksi['catatan'], + $inspeksi['pemeriksa'], + $inspeksi['pengirim'], + $user['M_UserID'] + ]); + if (!$queInspeksi) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert data inspeksi item"); + exit; + } + + # po item received && log item change # + $jsonBefore = $this->getPOItemReceived($obj['PoItemReceiveID']); + $sqlupd = "UPDATE po_item_receive SET + PoItemReceiveQtyReceived = ?, + PoItemReceiveUpdatedUserID = ? + WHERE PoItemReceiveID = ?"; + $queupd = $this->db->query($sqlupd, [ + (intval($cekReceived['PoItemReceiveQtyReceived']) + intval($obj['qty'])), + $user['M_UserID'], + $obj['PoItemReceiveID'] + ]); + if (!$queupd) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update item receive"); + exit; + } + + $jsonAfter = $this->getPOItemReceived($obj['PoItemReceiveID']); + $desc = "Diterima {$obj['M_ItemDesc']} sejumlah {$obj['qty']} {$obj['ItemUnitName']} di RO nomor {$numGR} *RO belum di konfirmasi"; + $this->insertLogPoItemReceive( + $obj['PoItemReceiveID'], + 'UPDATE', + $roID, + $jsonBefore, + $jsonAfter, + $user['M_UserID'], + $desc + ); + } + + $dataROAfter = $this->getDataROPO($roID); + $this->insertLogReceiveOrderPo($roID, 'ADD', '', $dataROAfter, $user['M_UserID'], implode("\n", $logDesc)); + $this->insertUserActivty($roID, 'RO', 'ADD', $user['M_UserID'], implode("\n", $logDesc)); + + $this->db->trans_commit(); + $this->sys_ok("Berhasil terima barang dengan nomor {$numGR}"); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function saveEditRO() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $this->db->trans_begin(); + $param = $this->sys_input; + $user = $this->sys_user; + + $sql_ro = "UPDATE receive_order_po SET + ReceiveOrderPoNumber = ?, + ReceiveOrderPoSupplierID = ?, + ReceiveOrderPoIDate = ?, + ReceiveOrderPoWarehouseID = ?, + ReceiveOrderPoM_BranchCode = ?, + ReceiveOrderPoS_RegionalID = ?, + ReceiveOrderShippingCostAmount = ?, + ReceiveOrderShippingCostIsPaid = ?, + ReceiveOrderPoNote = ?, + ReceiveOrderPoRefNumber = ?, + ReceiveOrderPoDONumber = ? + WHERE ReceiveOrderPoID = ?"; + $que_ro = $this->db->query($sql_ro, [ + $param['numGR'], + $param['supplierID'], + $param['date'], + $param['warehouseID'], + $user['M_BranchCode'], + $user['S_RegionalID'], + $param['shippingCost'], + $param['shippingIsPaid'], + $param['note'], + $param['refNumber'], + $param['refNumber'], + $param['ReceiveOrderID'] + ]); + if (!$que_ro) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert into table receive order po"); + exit; + } + + # CHECK IF DETAIL ALREADY IN TABLE RECEIVE # + $sql_check_ro = "SELECT ReceiveOrderPoDetailID, ReceiveOrderPoDetailPoItemReceiveID + FROM receive_order_po_detail + WHERE ReceiveOrderPoDetailReceiveOrderPoID = ? + AND ReceiveOrderPoDetailIsActive = 'Y'"; + $que_check_ro = $this->db->query($sql_check_ro, [$param['ReceiveOrderID']]); + if (!$que_check_ro) { + $this->db->trans_rollback(); + $this->sys_error("[Error] get list ro detail id"); + exit; + } + $list_detailID = $que_check_ro->result_array(); + $master_detailID = array_column($list_detailID, 'ReceiveOrderPoDetailID'); + $input_detailID = array_column($param['detail'], 'ReceiveOrderPoDetailID'); + + $update = []; + $insert = []; + $delete = []; + + foreach ($param['detail'] as $key => $obj) { + if (empty($obj['ReceiveOrderPoDetailID'])) { + $insert[] = $obj; + continue; + } + if (in_array($obj['ReceiveOrderPoDetailID'], $master_detailID)) { + $update[] = $obj; + } + } + + foreach ($list_detailID as $key => $obj) { + if (!in_array($obj['ReceiveOrderPoDetailID'], $input_detailID)) { + $delete[] = $obj; + } + } + + # UPDATE # + foreach ($update as $key => $obj) { + # cek item received # + $sqlRcvdItem = "SELECT * FROM po_item_receive WHERE PoItemReceiveID = ?"; + $queRcvdItem = $this->db->query($sqlRcvdItem, [$obj['PoItemReceiveID']]); + if (!$queRcvdItem) { + $this->db->trans_rollback(); + $this->sys_error_db("Error cek data item po_item_receive"); + exit; + } + $cekReceived = $queRcvdItem->row_array(); + if ($cekReceived['PoItemReceiveIsActive'] == 'N') { + $this->db->trans_rollback(); + $this->sys_error("[Error] Item {$obj['M_ItemDesc']} tidak aktif"); + exit; + } + + if (intval($obj['qty']) > intval($cekReceived['PoItemReceiveQty'])) { + $this->db->trans_rollback(); + $this->sys_error("Jumlah item {$obj['M_ItemDesc']} yang tersedia sudah berubah silahkan ulangi pilih item"); + exit; + } + + # UPDATE po item receive # + $sql_up_po_receive = "UPDATE po_item_receive + JOIN receive_order_po_detail ON ReceiveOrderPoDetailPoItemReceiveID = PoItemReceiveID + AND ReceiveOrderPoDetailID = ? + SET + PoItemReceiveQtyReceived = (PoItemReceiveQtyReceived - ReceiveOrderPoDetailQty) + ?, + PoItemReceiveUpdatedUserID = ? + WHERE PoItemReceiveID = ?"; + $que_up_po_receive = $this->db->query($sql_up_po_receive, [ + $obj['ReceiveOrderPoDetailID'], + $obj['qty'], + $user['M_UserID'], + $obj['PoItemReceiveID'] + ]); + if (!$que_up_po_receive) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update receive order detail"); + exit; + } + + # UPDATE receive detail po # + $jsonBatch = "[]"; + if (isset($obj['batchlist']) && is_array($obj['batchlist'])) { + $batchlist = $obj['batchlist']; + if (sizeof($batchlist) > 0) { + $json = json_encode($batchlist); + if ($json === false) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] encode json batch number"); + exit; + } else { + $jsonBatch = $json; + } + } + } + + $sql_update_detail = "UPDATE receive_order_po_detail SET + ReceiveOrderPoDetailReceiveOrderPoID = ?, + ReceiveOrderPoDetailPurchaseOrderID = ?, + ReceiveOrderPoDetailPurchaseOrderSummaryID = ?, + ReceiveOrderPoDetailPurchaseOrderDetailID = ?, + ReceiveOrderPoDetailPoItemReceiveID = ?, + ReceiveOrderPoDetailQty = ?, + ReceiveOrderPoDetailPrice = ?, + ReceiveOrderPoDetailTotal = ?, + ReceiveOrderPoItemID = ?, + ReceiveOrderPoItemUnitID = ?, + ReceiveOrderPoDetailBatchNo = ?, + ReceiveOrderPoDetailEd = ?, + ReceiveOrderPoDetailBatchList = ? + WHERE ReceiveOrderPoDetailID = ?"; + $que_update_detail = $this->db->query($sql_update_detail, [ + $param['ReceiveOrderID'], + $obj['PoItemReceivePurchaseOrderID'], + $obj['PoItemReceivePurchaseOrderSummaryID'], + $obj['PoItemReceivePurchaseOrderDetailID'], + $obj['PoItemReceiveID'], + $obj['qty'], + $obj['PoItemReceivePrice'], + (doubleval($obj['PoItemReceivePrice']) * intval($obj['qty'])), + $obj['M_ItemID'], + $obj['ItemUnitID'], + $obj['batchNo'], + $obj['itemEd'], + $jsonBatch, + $obj['ReceiveOrderPoDetailID'] + ]); + if (!$que_update_detail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update receive order detail"); + exit; + } + + # update form inspeksi item # + $inspeksi = $obj['inspeksi_item']; + $sql_inspeksi = "UPDATE receive_order_po_inspeksi SET + ReceiveOrderPoInspeksiQtyPesan = ?, + ReceiveOrderPoInspeksiQtyActual = ?, + ReceiveOrderPoInspeksiPricePesan = ?, + ReceiveOrderPoInspeksiPriceActual = ?, + ReceiveOrderPoInspeksiDatePesan = ?, + ReceiveOrderPoInspeksiDateActual = ?, + ReceiveOrderPoInspeksiKeadaanKemasan = ?, + ReceiveOrderPoInspeksiKeadaanKemasanNote = ?, + ReceiveOrderPoInspeksiKondisiPengiriman = ?, + ReceiveOrderPoInspeksiKondisiPengirimanNote = ?, + ReceiveOrderPoInspeksiSimpulan = ?, + ReceiveOrderPoInspeksiCatatan = ?, + ReceiveOrderPoInspeksiStaffPenerimaID = ?, + ReceiveOrderPoInspeksiPengirim = ? + WHERE ReceiveOrderPoInspeksiID = ?"; + $que_inspeksi = $this->db->query($sql_inspeksi, [ + $inspeksi['qty_po'], + $inspeksi['qty_ro'], + $inspeksi['price_po'], + $inspeksi['price_ro'], + $inspeksi['date_po'], + $inspeksi['date_ro'], + $inspeksi['condt_kemasan'], + $inspeksi['catatan_kemasan'], + $inspeksi['condt_pengiriman'], + $inspeksi['catatan_kirim'], + $inspeksi['summary'], + $inspeksi['catatan'], + $inspeksi['pemeriksa'], + $inspeksi['pemeriksa'], + $inspeksi['ReceiveOrderPoInspeksiID'] + ]); + if (!$que_inspeksi) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update form inspeksi"); + exit; + } + } + + # INSERT # + foreach ($insert as $key => $obj) { + # cek item received # + $sqlRcvdItem = "SELECT * FROM po_item_receive WHERE PoItemReceiveID = ?"; + $queRcvdItem = $this->db->query($sqlRcvdItem, [$obj['PoItemReceiveID']]); + if (!$queRcvdItem) { + $this->db->trans_rollback(); + $this->sys_error_db("Error cek data item po_item_receive"); + exit; + } + $cekReceived = $queRcvdItem->row_array(); + if ($cekReceived['PoItemReceiveIsActive'] == 'N') { + $this->db->trans_rollback(); + $this->sys_error("[Error] Item {$obj['M_ItemDesc']} tidak aktif"); + exit; + } + + if (intval($obj['qty']) > intval($cekReceived['PoItemReceiveQty'])) { + $this->db->trans_rollback(); + $this->sys_error("Jumlah item {$obj['M_ItemDesc']} yang tersedia sudah berubah silahkan ulangi pilih item"); + exit; + } + + # UPDATE po item receive # + $sql_up_po_receive = "UPDATE po_item_receive SET + PoItemReceiveQtyReceived = ?, + PoItemReceiveUpdatedUserID = ? + WHERE PoItemReceiveID = ?"; + $que_up_po_receive = $this->db->query($sql_up_po_receive, [ + (intval($cekReceived['PoItemReceiveQtyReceived']) + intval($obj['qty'])), + $user['M_UserID'], + $obj['PoItemReceiveID'] + ]); + if (!$que_up_po_receive) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update receive order detail"); + exit; + } + + $jsonBatch = "[]"; + if (isset($obj['batchlist']) && is_array($obj['batchlist'])) { + $batchlist = $obj['batchlist']; + if (sizeof($batchlist) > 0) { + $json = json_encode($batchlist); + if ($json === false) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] encode json batch number"); + exit; + } else { + $jsonBatch = $json; + } + } + } + + # RE-INSERT ITEM DETAIL # + $sql_insert_rodetail = "INSERT INTO receive_order_po_detail ( + ReceiveOrderPoDetailReceiveOrderPoID, + ReceiveOrderPoDetailPurchaseOrderID, + ReceiveOrderPoDetailPurchaseOrderSummaryID, + ReceiveOrderPoDetailPurchaseOrderDetailID, + ReceiveOrderPoDetailPoItemReceiveID, + ReceiveOrderPoDetailQty, + ReceiveOrderPoDetailPrice, + ReceiveOrderPoDetailTotal, + ReceiveOrderPoDetailCreatedUserID, + ReceiveOrderPoItemID, + ReceiveOrderPoItemUnitID, + ReceiveOrderPoDetailBatchNo, + ReceiveOrderPoDetailEd, + ReceiveOrderPoDetailBatchList + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $que_insert_rodetail = $this->db->query($sql_insert_rodetail, [ + $param['ReceiveOrderID'], + $obj['PoItemReceivePurchaseOrderID'], + $obj['PoItemReceivePurchaseOrderSummaryID'], + $obj['PoItemReceivePurchaseOrderDetailID'], + $obj['PoItemReceiveID'], + $obj['qty'], + $obj['PoItemReceivePrice'], + (doubleval($obj['PoItemReceivePrice']) * intval($obj['qty'])), + $user['M_UserID'], + $obj['M_ItemID'], + $obj['ItemUnitID'], + $obj['batchNo'], + $obj['itemEd'], + $jsonBatch + ]); + if (!$que_insert_rodetail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert receive order detail"); + exit; + } + $ro_detail_ID = $this->db->insert_id(); + + # INSERT form inspeksi item # + $inspekitem = $obj['inspeksi_item']; + $sql_insert_inspeksi = " INSERT INTO receive_order_po_inspeksi ( + ReceiveOrderPoInspeksiReceiveOrderPoDetailID, + ReceiveOrderPoInspeksiQtyPesan, + ReceiveOrderPoInspeksiQtyActual, + ReceiveOrderPoInspeksiPricePesan, + ReceiveOrderPoInspeksiPriceActual, + ReceiveOrderPoInspeksiDatePesan, + ReceiveOrderPoInspeksiDateActual, + ReceiveOrderPoInspeksiKeadaanKemasan, + ReceiveOrderPoInspeksiKeadaanKemasanNote, + ReceiveOrderPoInspeksiKondisiPengiriman, + ReceiveOrderPoInspeksiKondisiPengirimanNote, + ReceiveOrderPoInspeksiSimpulan, + ReceiveOrderPoInspeksiCatatan, + ReceiveOrderPoInspeksiStaffPenerimaID, + ReceiveOrderPoInspeksiPengirim, + ReceiveOrderPoInspeksiUserID + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $que_insert_inspeksi = $this->db->query($sql_insert_inspeksi, [ + $ro_detail_ID, + $inspekitem['qty_po'], + $inspekitem['qty_ro'], + $inspekitem['price_po'], + $inspekitem['price_ro'], + $inspekitem['date_po'], + $inspekitem['date_ro'], + $inspekitem['condt_kemasan'], + $inspekitem['catatan_kemasan'], + $inspekitem['condt_pengiriman'], + $inspekitem['catatan_kirim'], + $inspekitem['summary'], + $inspekitem['catatan'], + $inspekitem['pemeriksa'], + $inspekitem['pengirim'], + $user['M_UserID'] + ]); + if (!$que_insert_inspeksi) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert hasil form inspeksi"); + exit; + } + } + + # DELETE # + if (count($delete) > 0) { + $deleted_id = array_column($delete, 'ReceiveOrderPoDetailID'); + $placeholders = implode(', ', array_fill(0, count($deleted_id), '?')); + + $deleted_poid = array_column($delete, 'ReceiveOrderPoDetailPoItemReceiveID'); + $placeholders_po = implode(', ', array_fill(0, count($deleted_poid), '?')); + + # UPDATE po item receive # + $del_param = array_merge(array($user['M_UserID']), $deleted_poid, $deleted_id); + + $sql_up_po_receive = "UPDATE po_item_receive + JOIN receive_order_po_detail ON ReceiveOrderPoDetailPoItemReceiveID = PoItemReceiveID + SET PoItemReceiveQtyReceived = (PoItemReceiveQtyReceived - ReceiveOrderPoDetailQty), + PoItemReceiveUpdatedUserID = ? + WHERE PoItemReceiveID IN ($placeholders) + AND ReceiveOrderPoDetailID IN ($placeholders_po)"; + $que_up_po_receive = $this->db->query($sql_up_po_receive, $del_param); + if (!$que_up_po_receive) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update receive po item"); + exit; + } + + # UPDATE receive order po detail # + $upd_param = array_merge(array($user['M_UserID']), $deleted_id); + $sql_update_detail = "UPDATE receive_order_po_detail SET + ReceiveOrderPoDetailIsActive = 'N', + ReceiveOrderPoDetailDeleted = NOW(), + ReceiveOrderPoDetailDeletedUserID = ? + WHERE ReceiveOrderPoDetailID IN ($placeholders)"; + $que_update_detail = $this->db->query($sql_update_detail, $upd_param); + if (!$que_update_detail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update status receive order detail"); + exit; + } + + # update status table form inspeksi # + $deleted_inspeksi = array_map(function ($item) { + if (isset($item['inspeksi_item']['ReceiveOrderPoInspeksiID'])) { + return $item['inspeksi_item']['ReceiveOrderPoInspeksiID']; + } + return null; + }, $delete); + $placeholders_inspeksi = implode(', ', array_fill(0, count($deleted_inspeksi), '?')); + $delinspeksi_param = array_merge($user['M_UserID'], $deleted_inspeksi); + + $sql_inspeksi_status = "UPDATE receive_order_po_inspeksi SET + ReceiveOrderPoInspeksiIsActive = 'N', + ReceiveOrderPoInspeksiUserID = ?, + ReceiveOrderPoInspeksiDeleted = NOW() + WHERE ReceiveOrderPoInspeksiID IN ($placeholders_inspeksi)"; + $que_inspeksi_status = $this->db->query($sql_inspeksi_status, $delinspeksi_param); + if (!$que_inspeksi_status) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update status form receive item"); + exit; + } + + # update status barcode barang # + $sql_barcode = "UPDATE t_barcode_barang SET + T_BarcodeBarangIsActive = 'N', + T_BarcodeBarangUserID = ?, + T_BarcodeBarangLastUpdated = NOW() + WHERE T_BarcodeBarangReceiveOrderPoDetailID IN ($placeholders)"; + $qry_barcode = $this->db->query($sql_barcode, $upd_param); + if (!$qry_barcode) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update status barcode barang", $this->db); + exit; + } + } + + $this->db->trans_commit(); + $this->sys_ok("Success"); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function confirmRO() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $this->db->trans_begin(); + $param = $this->sys_input; + $user = $this->sys_user; + $ROID = $param['ROID']; + + # GET DATA RO # + $json_ro_before = $this->getDataROPO($ROID); + $sql_ro = "SELECT + receive_order_po.*, + DATE_FORMAT(ReceiveOrderPoIDate, '%d-%m-%Y') AS formatedDate, + CASE + WHEN WarehouseType = 'B' + THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName) + WHEN WarehouseType = 'R' + THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName) + ELSE '' + END WarehouseName, + WarehouseID + FROM receive_order_po + JOIN warehouse ON ReceiveOrderPoWarehouseID = WarehouseID + JOIN s_regional ON WarehouseS_RegionalID = S_RegionalID + AND S_RegionalIsActive = 'Y' + LEFT JOIN m_branch ON WarehouseM_BranchID = M_BranchID + AND M_BranchIsActive = 'Y' + WHERE ReceiveOrderPoID = ?"; + $que_ro = $this->db->query($sql_ro, [$ROID]); + if (!$que_ro) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get data RO"); + exit; + } + $data_ro = $que_ro->row_array(); + if ($data_ro['ReceiveOrderPoConfirmed'] == 'Y') { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] item dari RO{$data_ro['ReceiveOrderPoNumber']} sudah pernah di konfirmasi"); + exit; + } + + $sql_detail_ro = "SELECT + receive_order_po_detail.*, + PurchaseOrderID, + PurchaseOrderNumber, + PurchaseOrderTaxPercentPph, + PurchaseOrderTaxPercentPpn, + PurchaseOrderSummaryDiscountAmount as DiscountPerItem, + PurchaseOrderSummaryQty as QtyAllPO, + PurchaseOrderSummaryTotal as TotalAllPO, + PurchaseOrderDiscountPercent AS DiscPOPercent, + PurchaseOrderDiscountAmount AS DiscPORupiah + FROM receive_order_po_detail + JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID + JOIN purchase_order_summary ON ReceiveOrderPoDetailPurchaseOrderSummaryID = PurchaseOrderSummaryID + AND PurchaseOrderSummaryIsActive = 'Y' + WHERE ReceiveOrderPoDetailReceiveOrderPoID = ? + AND ReceiveOrderPoDetailIsActive='Y' + GROUP BY ReceiveOrderPoDetailID"; + $que_detail_ro = $this->db->query($sql_detail_ro, [$ROID]); + if (!$que_detail_ro) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get detail data ro"); + exit; + } + $data_detail_ro = $que_detail_ro->result_array(); + + # UPDATE STATUS RO # + $sql_update_ro = "UPDATE receive_order_po SET + ReceiveOrderPoConfirmed = 'Y', + ReceiveOrderPoConfirmedDate = NOW(), + ReceiveOrderPoConfirmedUserID = ? + WHERE ReceiveOrderPoID = ?"; + $que_update_ro = $this->db->query($sql_update_ro, [$user['M_UserID'], $ROID]); + if (!$que_update_ro) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get update status ro"); + exit; + } + + # PREPARE DATA FOR JURNAL # + $sql_jrnl_num = "SELECT `fn_numbering`('J') AS numbering"; + $que_jrnl_num = $this->db->query($sql_jrnl_num, []); + if (!$que_jrnl_num) { + $this->sys_error_db("[Error] generate jurnal number"); + $this->db->trans_rollback(); + exit; + } + $jurnal_number = $que_jrnl_num->row_array()['numbering']; + + $sql_periode = "SELECT periodeID FROM periode + WHERE DATE(NOW()) BETWEEN periodeStartDate AND periodeEndDate + AND periodeIsActive= 'Y' AND periodeIsClosed = 'N'"; + $que_periode = $this->db->query($sql_periode, []); + if (!$que_periode) { + $this->sys_error_db("[Error] get periode", $this->db); + $this->db->trans_rollback(); + exit; + } + if ($que_periode->num_rows() === 0) { + $this->sys_error_db("[Error] waktu periode tidak ditemukan", $this->db); + $this->db->trans_rollback(); + exit; + } + $jurnal_periode = $que_periode->row_array()['periodeID']; + + $sql_jrnl_type = "SELECT JurnalTypeID FROM jurnal_type WHERE JurnalTypeCode = ? AND JurnalTypeIsActive = 'Y'"; + $que_jrnl_type = $this->db->query($sql_jrnl_type, ['AUTOGOODRECEIVE']); + if (!$que_jrnl_type) { + $this->sys_error_db("[Error] get jurnal type", $this->db); + $this->db->trans_rollback(); + exit; + } + if ($que_jrnl_type->num_rows() === 0) { + $this->sys_error_db("[Error] tipe jurnal tidak ditemukan", $this->db); + $this->db->trans_rollback(); + exit; + } + $jurnal_type = $que_jrnl_type->row_array()['JurnalTypeID']; + + $list_po_in_ro = array_column($data_detail_ro, 'PurchaseOrderNumber'); + $str_po = implode(', ', array_unique($list_po_in_ro)); + + $jurnal_title = "Jurnal Penerimaan Barang Dari PO {$str_po} Tanggal {$data_ro['formatedDate']}"; + $jurnal_desc = $jurnal_title . " Dengan Nomor DO {$data_ro['ReceiveOrderPoDONumber']} Di {$data_ro['WarehouseName']}"; + + # INSERT JURNAL HEADER # + $sql_head_jurnal = "INSERT INTO jurnal ( + jurnalM_BranchCompanyID, + JurnalS_RegionalID, + jurnalM_BranchCode, + jurnalperiodeID, + jurnalNo, + jurnalTitle, + jurnalDescription, + jurnalDate, + jurnalJurnalTypeID, + jurnalM_UserID + ) VALUES (?,?,?,?,?,?,?,NOW(),?,?)"; + $que_head_jurnal = $this->db->query($sql_head_jurnal, [ + $user['M_BranchCompanyID'], + $user['S_RegionalID'], + $user['M_BranchCode'], + $jurnal_periode, + $jurnal_number, + $jurnal_title, + $jurnal_desc, + $jurnal_type, + $user['M_UserID'] + ]); + if (!$que_head_jurnal) { + $this->sys_error_db("[Error] insert header jurnal", $this->db); + $this->db->trans_rollback(); + exit; + } + $jurnal_ID = $this->db->insert_id(); + + $total_debet = 0.00; + $total_discount_item = 0.00; + $total_discount_po = 0.00; + $each_desc = []; + + foreach ($data_detail_ro as $key => $detail) { + # UPDATE PO Summary # + $sql_posummary = "UPDATE purchase_order_summary SET + PurchaseOrderSummaryQtyReceived = PurchaseOrderSummaryQtyReceived + ? + WHERE PurchaseOrderSummaryIsActive = 'Y' + AND PurchaseOrderSummaryID = ?"; + $que_posummary = $this->db->query($sql_posummary, [ + intval($detail['ReceiveOrderPoDetailQty']), + $detail['ReceiveOrderPoDetailPurchaseOrderSummaryID'] + ]); + if (!$que_posummary) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update qty received po summary"); + exit; + } + + $sql_cek_item = "SELECT * FROM m_item WHERE M_ItemID = ?"; + $que_cek_item = $this->db->query($sql_cek_item, [$detail['ReceiveOrderPoItemID']]); + if (!$que_cek_item) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] cek item received"); + exit; + } + $item_cek = $que_cek_item->row_array(); + if (empty($item_cek['M_ItemItem_CategoryID'])) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] kategori item {$item_cek['M_ItemDesc']} tidak ditemukan pada PO + {$detail['PurchaseOrderNumber']}"); + exit; + } + + # INSERT JURNAL TX # + if (intval($item_cek['M_ItemItem_CategoryID']) == 3) { + if (empty($item_cek['M_ItemFa_ClassID'])) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] class asset item {$item_cek['M_ItemDesc']} tidak ditemukan pada PO + {$detail['PurchaseOrderNumber']}"); + exit; + } + + $sql_coa_asset = "SELECT + Fa_ClassCoaID, + Fa_ClassCoaNo, + Fa_ClassCoaDesc + FROM fa_class + WHERE Fa_ClassID = ? + AND Fa_ClassIsActive = 'Y'"; + $que_coa_asset = $this->db->query($sql_coa_asset, [$item_cek['M_ItemFa_ClassID']]); + if (!$que_coa_asset) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] failed to get coa asset"); + exit; + } + $asset_coa = $que_coa_asset->row_array(); + + if (empty($asset_coa['Fa_ClassCoaID'])) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] coa class asset not found"); + exit; + } + + $debet = doubleval($detail['ReceiveOrderPoDetailTotal']); + $total_debet = round($total_debet + $debet, 2); + + # INSERT JURNAL TX DEBET # + $sql_tx_jurnal = "INSERT INTO jurnal_tx ( + jurnalTxJurnalID, + jurnalTxCoaID, + jurnalTxDescription, + jurnalTxDebit, + jurnalTxCredit, + jurnalTxM_UserID + ) VALUES (?,?,?,?,?,?)"; + $que_tx_jurnal = $this->db->query($sql_tx_jurnal, [ + $jurnal_ID, + $asset_coa['Fa_ClassCoaID'], + $asset_coa['Fa_ClassCoaDesc'], + $debet, + 0, + $user['M_UserID'] + ]); + if (!$que_tx_jurnal) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] failed insert jurnal tx {$item_cek['M_ItemDesc']} + PO {$detail['PurchaseOrderNumber']}"); + exit; + } + $juranl_tx_ID = $this->db->insert_id(); + $each_desc[] = "- Add detail Jurnal debet {$item_cek['M_ItemDesc']} + {$asset_coa['Fa_ClassCoaDesc']} sejumlah {$this->formatRupiah($debet)}"; + + # INSERT JURNAL ADDON # + $sql_addon_jurnal = "INSERT INTO jurnal_addon ( + jurnalAddOnJurnalID, + jurnalAddOnJurnalTxID, + jurnalAddOnCode, + jurnalAddOnValue, + jurnalAddOnM_ItemID, + jurnalAddOnCreated, + jurnalAddOnCreatedUserID + ) VALUES (?,?,'PONUMB',?,?,NOW(),?)"; + $que_addon_jurnal = $this->db->query($sql_addon_jurnal, [ + $jurnal_ID, + $juranl_tx_ID, + $detail['PurchaseOrderNumber'], + $detail['ReceiveOrderPoItemID'], + $user['M_UserID'] + ]); + if (!$que_addon_jurnal) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] failed insert jurnal addon {$item_cek['M_ItemDesc']} + PO {$detail['PurchaseOrderNumber']}"); + exit; + } + + # INSERT JURNAL TX KREDIT DISKON # + $sql_po = "SELECT + SUM(subquery.PurchaseOrderSummaryQty) as totalAllQtyPO, + SUM(subquery.PurchaseOrderSummaryTotal) as totalAllPricePO + FROM ( + SELECT + PurchaseOrderSummaryQty, + PurchaseOrderSummaryTotal + FROM receive_order_po_detail + JOIN purchase_order_summary ON PurchaseOrderSummaryPurchaseOrderID = ReceiveOrderPoDetailPurchaseOrderID + AND PurchaseOrderSummaryIsActive = 'Y' + WHERE ReceiveOrderPoDetailReceiveOrderPoID = ? + GROUP BY PurchaseOrderSummaryID + ) as subquery"; + $que_po = $this->db->query($sql_po, [$ROID]); + if (!$que_po) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get detail total qty and price of item po"); + exit; + } + $data_po = $que_po->row_array(); + + // calc diskon per item + $diskon = round(intval($detail['ReceiveOrderPoDetailQty'] * doubleval($detail['DiscountPerItem'])), 2); + $total_discount_item = round($total_discount_item + $diskon, 2); + + // calc diskon prorata PO untuk item + $diskon_po = doubleval($detail['DiscPORupiah']); + if (doubleval($detail['DiscPOPercent']) != 0.00) { + $diskon_po = doubleval($data_po['totalAllPricePO']) * doubleval($detail['DiscPOPercent']) / 100; + } + $diskon_prorata_po = $diskon_po * (doubleval($detail['TotalAllPO'])) / doubleval($data_po['totalAllPricePO']); + $diskon_prorata_item = round((intval($detail['ReceiveOrderPoDetailQty']) / intval($detail['QtyAllPO'])) * $diskon_prorata_po, 2); + + $total_discount_po = round($total_discount_po + $diskon_prorata_item, 2); + $input_diskon = [$diskon, $diskon_prorata_item]; + + // get account coa diskon + $sql_coa_disc = "SELECT * FROM coa WHERE coaAccountNo = ? LIMIT 1"; + $que_coa_disc = $this->db->query($sql_coa_disc, ['2190100001']); + if (!$que_coa_disc) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get account diskon"); + exit; + } + $coa_diskon = $que_coa_disc->row_array(); + + foreach ($input_diskon as $kkey => $value) { + if (doubleval($value) === 0.00) { + continue; + } + $que_tx_jurnal = $this->db->query($sql_tx_jurnal, [ + $jurnal_ID, + $coa_diskon['coaID'], + $coa_diskon['coaDescription'], + 0, + $value, + $user['M_UserID'] + ]); + if (!$que_tx_jurnal) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] failed insert jurnal tx diskon + item {$item_cek['M_ItemDesc']} PO {$detail['PurchaseOrderNumber']}"); + exit; + } + $juranl_txdisc_ID = $this->db->insert_id(); + $que_addon_jurnal = $this->db->query($sql_addon_jurnal, [ + $jurnal_ID, + $juranl_txdisc_ID, + $detail['PurchaseOrderNumber'], + $detail['ReceiveOrderPoItemID'], + $user['M_UserID'] + ]); + if (!$que_addon_jurnal) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] failed insert jurnal addon diskon + item {$item_cek['M_ItemDesc']} PO {$detail['PurchaseOrderNumber']}"); + exit; + } + } + + // save diskon prorata + $sql_save_diskon = "UPDATE receive_order_po_detail SET + ReceiveOrderPoDetailDiskonPoProrata = ? + WHERE ReceiveOrderPoDetailID = ?"; + $que_save_diskon = $this->db->query($sql_save_diskon, [ + $diskon_prorata_item, + $detail['ReceiveOrderPoDetailID'] + ]); + if (!$que_save_diskon) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] save diskon prorata + item {$item_cek['M_ItemDesc']} PO {$detail['PurchaseOrderNumber']}"); + exit; + } + } else { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] BE Jurnal tipe selain Asset tidak ada"); + exit; + } + + # HANDLE STOCK UPDATE # + // decode batchlist item diterima + $json_batch_item = $detail['ReceiveOrderPoDetailBatchList']; + $batch_list = []; + if (!empty($json_batch_item)) { + $decode = json_decode($json_batch_item, true); + if ($decode !== null && json_last_error() === JSON_ERROR_NONE) { + $batch_list = $decode; + } else { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] decode json for batches number"); + exit; + } + } + + // update stock based on batch + foreach ($batch_list as $key => $batch) { + $sql_cek_stock = "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_cek_stock = $this->db->query($sql_cek_stock, [ + $detail['ReceiveOrderPoItemID'], + $detail['ReceiveOrderPoItemUnitID'], + $data_ro['WarehouseID'], + $batch['item_category'] + ]); + if (!$que_cek_stock) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] check stock exist or not"); + exit; + } + $stock_exist = $que_cek_stock->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)) { + // calc new prive average + $stock_qty_end = $stock_qty_ori + intval($batch['qty']); + $all_price = ($stock_qty_ori * $stock_price) + (intval($batch['qty']) * doubleval($detail['ReceiveOrderPoDetailPrice'])); + $avg_prive = 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_prive, + $stock_qty_end, + $user['M_UserID'], + $stock_ID + ]); + if (!$que_update_stock) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert update stock"); + exit; + } + + // insert stockid barcode barang + // $sql_update_barcode = "UPDATE t_barcode_barang SET + // T_BarcodeBarangStockID = ? + // WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?"; + // $qry_update_barcode = $this->db->query($sql_update_barcode, [ + // $stock_ID, + // $detail['ReceiveOrderPoDetailID'] + // ]); + // if (!$qry_update_barcode) { + // $this->db->trans_rollback(); + // $this->sys_error_db("[Error] update barcode stockID", $this->db); + // exit; + // } + } else { + $sql_insert_stock = "INSERT INTO stock ( + StockWarehouseAlmariID, + 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['WarehouseID'], + $detail['ReceiveOrderPoItemID'], + $detail['ReceiveOrderPoItemUnitID'], + $detail['ReceiveOrderPoDetailPrice'], + $batch['qty'], + $user['M_UserID'] + ]); + if (!$que_insert_stock) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert new batch stock"); + exit; + } + + $stockID = $this->db->insert_id(); + $stock_qty_ori = 0; + $stock_qty_end = intval($batch['qty']); + + // insert stockid barcode barang + // $sql_update_barcode = "UPDATE t_barcode_barang SET + // T_BarcodeBarangStockID = ? + // WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?"; + // $qry_update_barcode = $this->db->query($sql_update_barcode, [ + // $stockID, + // $detail['ReceiveOrderPoDetailID'] + // ]); + // if (!$qry_update_barcode) { + // $this->db->trans_rollback(); + // $this->sys_error_db("[Error] update barcode stockID", $this->db); + // exit; + // } + } + + // insert stock card + $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['WarehouseID'], + $detail['ReceiveOrderPoItemID'], + $detail['ReceiveOrderPoItemUnitID'], + $stock_ID, + $stock_qty_ori, + $batch['qty'], + $stock_qty_end, + $user['M_UserID'] + ]); + if (!$que_stock_card) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert stock card"); + exit; + } + + // 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(); + $this->sys_error_db("[Error] get latest stock"); + exit; + } + $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'], + $detail['ReceiveOrderPoItemID'], + $detail['ReceiveOrderPoItemUnitID'], + $stock_latest['StockStockNumber'], + $stock_ID, + $batch['qty'], + $user['M_UserID'] + ]); + if (!$que_stock_log) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get latest stock"); + exit; + } + } + } + + # insert shipping cost ke jurnal # + $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, [$jurnal_ID, $ship_cost, $user['M_UserID']]); + if (!$que_tx_ship) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert jurnal tx shipping cost"); + exit; + } + } + + // insert jurnal tx for GRNI + $total_grni = round($total_debet - ($total_discount_item + $total_discount_po), 2) + $ship_cost; + $sql_grni = "INSERT INTO jurnal_tx ( + jurnalTxJurnalID, + jurnalTxCoaID, + jurnalTxDescription, + jurnalTxDebit, + jurnalTxCredit, + jurnalTxM_UserID + ) SELECT ?, coaID, coaDescription, 0, ?, ? + FROM coa WHERE coaAccountNo = '2110100030' LIMIT 1"; + $que_grni = $this->db->query($sql_grni, [$jurnal_ID, $total_grni, $user['M_UserID']]); + if (!$que_grni) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert jurnal tx GRNI"); + exit; + } + $grni_jurnal_id = $this->db->insert_id(); + + $sql_addon_grni = "INSERT INTO jurnal_addon ( + jurnalAddOnJurnalID, + jurnalAddOnJurnalTxID, + jurnalAddOnCode, + jurnalAddOnValue, + jurnalAddOnCreated, + jurnalAddOnCreatedUserID + ) VALUES (?,?,'RONUMB',?,NOW(),?)"; + $que_addon_grni = $this->db->query($sql_addon_grni, [ + $jurnal_ID, + $grni_jurnal_id, + $data_ro['ReceiveOrderPoNumber'], + $user['M_UserID'] + ]); + if (!$que_addon_grni) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert jurnal addon GRNI"); + exit; + } + + # insert into shipping table # + $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(); + $this->sys_error_db("[Error] insert table shipping cost"); + exit; + } + + # LOG # + $desc = "Konfirmasi penerimaan barang {$data_ro['ReceiveOrderPoNumber']} Tanggal {$data_ro['formatedDate']} + di {$data_ro['WarehouseName']} yang meliputi beberapa item dari PO {$str_po}"; + $log_desc = $desc . "\n" . implode("\n", $each_desc); + + $json_ro_after = $this->getDataROPO($ROID); + $this->insertLogReceiveOrderPo($ROID, 'CONFIRM', $json_ro_before, $json_ro_after, $user['M_UserID'], $log_desc); + $this->insertUserActivty($ROID, 'RO', 'CONFIRM', $user['M_UserID'], $log_desc); + + # GENERATE PURCHASE INVOICE # + $this->generatePurchaseInvoice($user, $ROID, $total_grni, $total_discount_po, $ship_cost); + + $this->db->trans_commit(); + $this->sys_ok("[Success] Berhasil konfirmasi terima barang"); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function deleteRO() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $this->db->trans_begin(); + $param = $this->sys_input; + $user = $this->sys_user; + + $ROID = $param['ROID']; + + # data before fo logging # + $json_ro_before = $this->getDataROPO($ROID); + + # update status header RO # + $sql = "UPDATE receive_order_po SET + ReceiveOrderPoIsActive = 'N', + ReceiveOrderPoDeleted = NOW(), + ReceiveOrderPoDeletedUserID = ? + WHERE ReceiveOrderPoID = ?"; + $que = $this->db->query($sql, [$user['M_UserID'], $ROID]); + if (!$que) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] delete receive oder"); + exit; + } + + $sql_detail = "SELECT * FROM receive_order_po_detail + WHERE ReceiveOrderPoDetailReceiveOrderPoID = ? + AND ReceiveOrderPoDetailIsActive = 'Y'"; + $que_detail = $this->db->query($sql_detail, [$ROID]); + if (!$que_detail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get detail RO "); + exit; + } + $details = $que_detail->result_array(); + + # update status detail RO # + foreach ($details as $key => $detail) { + # update receive detail po # + $sql_update_detail = "UPDATE receive_order_po_detail SET + ReceiveOrderPoDetailIsActive = 'N', + ReceiveOrderPoDetailDeletedUserID = ?, + ReceiveOrderPoDetailDeleted = NOW() + WHERE ReceiveOrderPoDetailID = ?"; + $que_update_detail = $this->db->query($sql_update_detail, [ + $user['M_UserID'], + $detail['ReceiveOrderPoDetailID'] + ]); + if (!$que_update_detail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update status detail RO"); + exit; + } + + # update status form inspeksi # + $sql_inspeksi = "UPDATE receive_order_po_inspeksi SET + ReceiveOrderPoInspeksiIsActive = 'N' + WHERE ReceiveOrderPoInspeksiReceiveOrderPoDetailID = ? "; + $que_inspeksi = $this->db->query($sql_inspeksi, [$detail['ReceiveOrderPoDetailID']]); + if (!$que_inspeksi) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update status form inspeksi"); + exit; + } + + # update status barcode barang # + $sql_barcode = "UPDATE t_barcode_barang SET + T_BarcodeBarangIsActive = 'N', + T_BarcodeBarangUserID = ?, + T_BarcodeBarangLastUpdated = NOW() + WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?"; + $qry_barcode = $this->db->query($sql_barcode, [ + $user['M_UserID'], + $detail['ReceiveOrderPoDetailID'] + ]); + if (!$qry_barcode) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update status barcode barang", $this->db); + exit; + } + + # update po item receive # + $json_po_before = $this->getPOItemReceived($detail['ReceiveOrderPoDetailPoItemReceiveID']); + $sql_upd_po_received = "UPDATE po_item_receive + JOIN receive_order_po_detail ON PoItemReceiveID = ReceiveOrderPoDetailPoItemReceiveID + AND ReceiveOrderPoDetailReceiveOrderPoID = ? + AND ReceiveOrderPoDetailID = ? + SET PoItemReceiveQtyReceived = PoItemReceiveQtyReceived - ReceiveOrderPoDetailQty, + PoItemReceiveUpdatedUserID = ? + WHERE PoItemReceiveID = ?"; + $que_upd_po_received = $this->db->query($sql_upd_po_received, [ + $ROID, + $detail['ReceiveOrderPoDetailID'], + $user['M_UserID'], + $detail['ReceiveOrderPoDetailPoItemReceiveID'] + ]); + if (!$que_upd_po_received) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update qty PO item received"); + exit; + } + $json_po_after = $this->getPOItemReceived($detail['ReceiveOrderPoDetailPoItemReceiveID']); + $descItem = "Dihapus {$detail['M_ItemDesc']} sejumlah {$detail['ReceiveOrderPoDetailQty']} + {$detail['ItemUnitName']} di RO nomor {$json_ro_before['ReceiveOrderPoNumber']} + *RO belum di konfirmasi"; + + # log # + $this->insertLogPoItemReceive( + $detail['ReceiveOrderPoDetailPoItemReceiveID'], + 'UPDATE', + $ROID, + $json_po_before, + $json_po_after, + $user['M_UserID'], + $descItem + ); + } + + $json_ro_after = $this->getDataROPO($ROID); + $this->insertLogReceiveOrderPo( + $ROID, + 'DELETE', + $json_ro_before, + $json_ro_after, + $user['M_UserID'], + "Update data RO ID: {$ROID}" + ); + + $this->insertUserActivty($ROID, 'RO', 'DELETE', $user['M_UserID'], "Update data RO ID: {$ROID}"); + + $this->db->trans_commit(); + $this->sys_ok("[Success]"); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function saveInspeksi() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $param = $this->sys_input; + $user = $this->sys_user; + + # Prepare Data # + $inspeksi = $param['form_inspeksi']; + $ROdetailID = $param['ROdetailID']; + + # Insert Query # + $this->db->trans_begin(); + + $sql_insert = "INSERT INTO receive_order_po_inspeksi ( + ReceiveOrderPoInspeksiReceiveOrderPoDetailID, + ReceiveOrderPoInspeksiQtyPesan, + ReceiveOrderPoInspeksiQtyActual, + ReceiveOrderPoInspeksiPricePesan, + ReceiveOrderPoInspeksiPriceActual, + ReceiveOrderPoInspeksiDatePesan, + ReceiveOrderPoInspeksiDateActual, + ReceiveOrderPoInspeksiExpireDate, + ReceiveOrderPoInspeksiKeadaanKemasan, + ReceiveOrderPoInspeksiKondisiPengiriman, + ReceiveOrderPoInspeksiSimpulan, + ReceiveOrderPoInspeksiCatatan, + ReceiveOrderPoInspeksiStaffPenerima, + ReceiveOrderPoInspeksiStaffPengirim, + ReceiveOrderPoInspeksiUserID + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $que_insert = $this->db->query($sql_insert, [ + $ROdetailID, + $inspeksi['qty_po'], + $inspeksi['qty_ro'], + $inspeksi['price_po'], + $inspeksi['price_ro'], + $inspeksi['date_po'], + $inspeksi['date_ro'], + $inspeksi['expire_date'], + $inspeksi['condt_kemasan'], + $inspeksi['condt_pengiriman'], + $inspeksi['summary'], + $inspeksi['catatan'], + $inspeksi['pemeriksa'], + $inspeksi['pengirim'], + $user['M_UserID'] + ]); + if (!$que_insert) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert into table receiec order po inspeksi"); + exit; + } + + $this->db->trans_commit(); + $this->sys_ok("[Success] save inspeksi item"); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function generateItemPO() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $param = $this->sys_input; + $userid = $this->sys_user; + $POID = $param['id']; + + if (!isset($POID)) { + $this->sys_error("Missing required parameters"); + exit; + } + + $this->db->trans_begin(); + + $sql_po = "SELECT * FROM purchase_order WHERE PurchaseOrderID = ?"; + $que_po = $this->db->query($sql_po, [$POID]); + if (!$que_po) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get data PO"); + exit; + } + $data_po = $que_po->row_array(); + + if ($data_po['PurchaseOrderStatus'] != 'Approved') { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] status PO belum Approved"); + exit; + } + + $data_detail = []; + + if (strtolower($data_po['PurchaseOrderWarehouseType']) == 'single') { + $sql_POdetail = "SELECT + IFNULL(pir.PoItemReceiveID, 0) as receivedID, + IFNULL(pir.PoItemReceiveQtyReceived, 0) as qtyReceived, + pos.PurchaseOrderSummaryID as orderSummaryID, + pos.PurchaseOrderSummaryItemID as itemID, + pos.PurchaseOrderSummaryItemUnitID as itemUnitID, + pos.PurchaseOrderSummaryQty as qty, + pos.PurchaseOrderSummaryPrice as price, + m_itemDesc as itemName, + ItemUnitName as itemUnitName, + PurchaseOrderDetailID + FROM purchase_order_summary pos + JOIN purchase_order_detail ON PurchaseOrderDetailPurchaseOrderID = pos.PurchaseOrderSummaryPurchaseOrderID + AND PurchaseOrderSummaryItemID = PurchaseOrderDetailItemID + AND PurchaseOrderSummaryItemUnitID = PurchaseOrderDetailItemUnitID + JOIN m_item ON pos.PurchaseOrderSummaryItemID = M_ItemID + JOIN itemunit ON pos.PurchaseOrderSummaryItemUnitID = ItemUnitID + LEFT JOIN po_item_receive pir ON pos.PurchaseOrderSummaryPurchaseOrderID = pir.PoItemReceivePurchaseOrderID + AND pos.PurchaseOrderSummaryItemID = pir.PoItemReceiveItemID + WHERE pos.PurchaseOrderSummaryPurchaseOrderID = ? + AND pos.PurchaseOrderSummaryIsActive = 'Y' + AND IFNULL(pir.PoItemReceiveQtyReceived, 0) = 0"; + $que_POdetail = $this->db->query($sql_POdetail, [$POID]); + if (!$que_POdetail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get data detail PO"); + exit; + } + $data_detail = $que_POdetail->result_array(); + + foreach ($data_detail as $key => $obj) { + if (intval($obj['PoItemReceiveID']) == 0) { + $sql_ins = "INSERT INTO po_item_receive ( + PoItemReceivePurchaseOrderID, + PoItemReceivePurchaseOrderSummaryID, + PoItemReceivePurchaseOrderDetailID, + PoItemReceiveWarehouseID, + PoItemReceiveItemID, + PoItemReceiveItemUnitID, + PoItemReceiveQty, + PoItemReceiveQtyReceived, + PoItemReceiveIsActive, + PoItemReceiveCreated, + PoItemReceiveCreatedUserID, + PoItemReceivePrice + ) VALUES (?,?,?,?,?,?,?,0,'Y',NOW(),?,?)"; + $que_ins = $this->db->query($sql_ins, [ + $POID, + $obj['orderSummaryID'], + $obj['PurchaseOrderDetailID'], + $data_po['PurchaseOrderWarehouseID'], + $obj['itemID'], + $obj['itemUnitID'], + $obj['qty'], + $userid, + $obj['price'] + ]); + if (!$que_ins) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert po item receive"); + exit; + } + $insertedID = $this->db->insert_id(); + + $desc = "ADD {$obj['itemName']} {$obj['qty']} {$obj['itemUnitName']} {$data_po['WarehouseName']}"; + $jsonAfter = $this->getPOItemReceived($insertedID); + $this->insertLogPoItemReceive($insertedID, 'ADD', 0, '', $jsonAfter, $userid, $desc); + } else { + $jsonBefore = $this->getPOItemReceived($obj['PoItemReceiveID']); + $sql_upd = "UPDATE po_item_receive SET + PoItemReceiveQty = ?, + PoItemReceiveIsActive = 'Y', + PoItemReceiveUpdate = NOW(), + PoItemReceiveUpdatedUserID = ?, + PoItemReceiveWarehouseID = ?, + PoItemReceiveItemUnitID = ?, + PoItemReceivePrice = ? + WHERE PoItemReceiveID = ?"; + $que_upd = $this->db->query($sql_upd, [ + $obj['qty'], + $userid, + $data_po['PurchaseOrderWarehouseID'], + $obj['itemUnitID'], + $obj['price'], + $obj['receivedID'] + ]); + if (!$que_upd) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update po item receive"); + exit; + } + + $jsonAfter = $this->getPOItemReceived($obj['PoItemReceiveID']); + $desc = "UPDATE {$obj['itemName']} {$obj['qty']} {$obj['itemUnitName']} {$data_po['WarehouseName']}"; + $this->insertLogPoItemReceive($obj['PoItemReceiveID'], 'UPDATE', 0, $jsonBefore, $jsonAfter, $userid, $desc); + } + } + } + + if (strtolower($data_po['PurchaseOrderWarehouseType']) == 'multiple') { + $sql_det = "SELECT + IFNULL(PoItemReceiveID, 0) as cekID, + IFNULL(PoItemReceiveQtyReceived, 0) as qtyCek, + pod.PurchaseOrderDetailPurchaseSummaryID as summaryID, + pod.PurchaseOrderDetailID as poDetailID, + pod.PurchaseOrderDetailWarehouseID as warehouseID, + WarehouseName, + pod.PurchaseOrderDetailItemID as itemID, + M_ItemDesc as itemName, + pos.PurchaseOrderSummaryItemUnitID as itemUnitID, + ItemUnitName as itemUnitName, + ConvertQuantityToPurchasedItemUnit( + pod.PurchaseOrderDetailItemID, + pod.PurchaseOrderDetailItemUnitID, + pod.PurchaseOrderDetailQty + ) as poQty, + pos.PurchaseOrderSummaryPrice as price + FROM purchase_order_detail pod + JOIN purchase_order_summary pos ON pod.PurchaseOrderDetailPurchaseSummaryID = pos.PurchaseOrderSummaryID + JOIN m_item ON pod.PurchaseOrderDetailItemID = M_ItemID + JOIN itemunit ON pos.PurchaseOrderSummaryItemUnitID = ItemUnitID + JOIN warehouse ON pod.PurchaseOrderDetailWarehouseID = WarehouseID + LEFT JOIN po_item_receive p ON p.PoItemReceiveItemID = pod.PurchaseOrderDetailItemID + AND p.PoItemReceivePurchaseOrderID = ? + AND p.PoItemReceivePurchaseOrderSummaryID = pos.PurchaseOrderSummaryID + AND p.PoItemReceivePurchaseOrderDetailID = pod.PurchaseOrderDetailID + WHERE pod.PurchaseOrderDetailPurchaseOrderID = ? + AND IFNULL(PoItemReceiveQtyReceived, 0) = 0 + AND pod.PurchaseOrderDetailIsActive = 'Y'"; + $que_det = $this->db->query($sql_det, [$POID, $POID]); + if (!$que_det) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get item"); + exit; + } + $data_detail = $que_det->result_array(); + + foreach ($data_detail as $key => $obj) { + if (intval($obj['cekID']) == 0) { + $sql_ins = "INSERT INTO po_item_receive ( + PoItemReceivePurchaseOrderID, + PoItemReceivePurchaseOrderSummaryID, + PoItemReceivePurchaseOrderDetailID, + PoItemReceiveWarehouseID, + PoItemReceiveItemID, + PoItemReceiveItemUnitID, + PoItemReceiveQty, + PoItemReceiveQtyReceived, + PoItemReceiveIsActive, + PoItemReceiveCreated, + PoItemReceiveCreatedUserID, + PoItemReceivePrice + ) VALUES (?,?,?,?,?,?,?,0,'Y',NOW(),?,?)"; + $que_ins = $this->db->query($sql_ins, [ + $POID, + $obj['summaryID'], + $obj['poDetailID'], + $obj['warehouseID'], + $obj['itemID'], + $obj['itemUnitID'], + $obj['poQty'], + $userid, + $obj['price'] + ]); + if (!$que_ins) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert po item receive multiple wh"); + exit; + } + $insertedID = $this->db->insert_id(); + + $desc = "ADD {$obj['itemName']} {$obj['poQty']} {$obj['itemUnitName']} {$obj['WarehouseName']}"; + $jsonAfter = $this->getPOItemReceived($insertedID); + $this->insertLogPoItemReceive($insertedID, 'ADD', 0, '', $jsonAfter, $userid, $desc); + } else { + $jsonBefore = $this->getPOItemReceived($obj['cekID']); + + $sql_upd = "UPDATE po_item_receive SET + PoItemReceiveQty = ?, + PoItemReceiveIsActive = 'Y', + PoItemReceiveUpdate = NOW(), + PoItemReceiveUpdatedUserID = ?, + PoItemReceiveWarehouseID = ?, + PoItemReceiveItemUnitID = ?, + PoItemReceivePrice = ? + WHERE PoItemReceiveID = ?"; + $que_upd = $this->db->query($sql_upd, [ + $obj['poQty'], + $userid, + $obj['warehouseID'], + $obj['itemUnitID'], + $obj['price'], + $obj['cekID'] + ]); + if (!$que_upd) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update po item receive multiple wh"); + exit; + } + + $desc = "ADD {$obj['itemName']} {$obj['poQty']} {$obj['itemUnitName']} {$obj['WarehouseName']}"; + $jsonAfter = $this->getPOItemReceived($obj['cekID']); + $this->insertLogPoItemReceive($obj['cekID'], 'UPDATE', 0, $jsonBefore, $jsonAfter, $userid, $desc); + } + } + } + + $this->db->trans_commit(); + $this->sys_ok([ + 'header' => $data_po, + 'detail' => $data_detail + ]); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function saveHandover() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $this->db->trans_begin(); + $param = $this->sys_input; + $user = $this->sys_user; + + # Ambil data PurchaseRequestID # + $sql_get_prid = "SELECT DISTINCT + pod.PurchaseOrderDetailPurchaseRequestID AS PurchaseRequestID + FROM receive_order_po_detail ropd + JOIN purchase_order_detail pod ON pod.PurchaseOrderDetailID = ropd.ReceiveOrderPoDetailPurchaseOrderDetailID + WHERE ropd.ReceiveOrderPoDetailReceiveOrderPoID = ? + AND pod.PurchaseOrderDetailPurchaseRequestID IS NOT NULL"; + $que_get_prid = $this->db->query($sql_get_prid, [$param['receiveOrderPoID']]); + if (!$que_get_prid) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get PurchaseRequestID from RO Detail"); + exit; + } + $data_prid = $que_get_prid->row_array(); + + # insert handover # + $sql_insert_handover = "INSERT INTO asset_handover( + AssetHandoverPurchaseRequestID, + AssetHandoverReceiveOrderPoID, + AssetHandoverDate, + AssetHandoverM_RuanganID, + AssetHandoverToUserID, + AssetHandoverIsActive, + AssetHandoverCreated, + AssetHandoverUserID + ) VALUES(?,?,NOW(),?,?,'Y',NOW(),?)"; + $qry_insert_handover = $this->db->query($sql_insert_handover, [ + $data_prid['PurchaseRequestID'], + $param['receiveOrderPoID'], + $param['ruanganID'], + $param['staffID'], + $user['M_UserID'] + ]); + if (!$qry_insert_handover) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert asset handover"); + exit; + } + + $handoverID = $this->db->insert_id(); + + foreach ($param['item'] as $key => $item) { + $qty_invnt = intval($item['serahQty']); + for ($i = 0; $i < $qty_invnt; $i++) { + + # generate barcode number each inventory item # + $noBarcode = $this->generateNoBarcode($user, $param['ruanganID'], 'BNP', $item['ReceiveOrderPoItemID']); + $sql_insert_barcode = "INSERT INTO t_barcode_barang( + T_BarcodeBarangReceiveOrderPoID, + T_BarcodeBarangReceiveOrderPoDetailID, + T_BarcodeBarangRefType, + T_BarcodeBarangM_ItemID, + T_BarcodeBarangItemUnitID, + T_BarcodeBarangNumber, + T_BarcodeBarangM_RuanganID, + T_BarcodeBarangM_BranchID, + T_BarcodeBarangIsActive, + T_BarcodeBarangUserID, + T_BarcodeBarangCreated + ) VALUES(?,?,'PO',?,?,?,?,?,'Y',?,NOW())"; + $que_insert_barcode = $this->db->query($sql_insert_barcode, [ + $param['receiveOrderPoID'], + $item['ReceiveOrderPoDetailID'], + $item['ReceiveOrderPoItemID'], + $item['ReceiveOrderPoItemUnitID'], + $noBarcode, + $param['ruanganID'], + $user['M_BranchID'], + $user['M_UserID'] + ]); + if (!$que_insert_barcode) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert no barcode invetaris"); + exit; + } + + $barcodeID = $this->db->insert_id(); + + # check if item already in stock # + $sql_cekstock = "SELECT StockID + FROM stock + JOIN warehouse ON WarehouseID = StockWarehouseID + AND WarehouseIsActive = 'Y' + WHERE WarehouseM_BranchID = ? + AND StockItemID = ? + AND StockItemUnitID = ?"; + $que_cekstock = $this->db->query($sql_cekstock, [ + $user['M_BranchID'], + $item['ReceiveOrderPoItemID'], + $item['ReceiveOrderPoItemUnitID'], + ]); + if (!$que_cekstock) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] query cek stock"); + exit; + } + $stockID = $que_cekstock->row_array()['StockID']; + + # insert stock inventaris # + $sql_stockinventaris = "INSERT INTO stock_inventory ( + StockInventoryStockID, + StockInventoryRuanganID, + StockInventoryBarcode, + StockInventoryBranchID, + StockInventoryCreatedUserID + ) VALUES (?,?,?,?,?)"; + $que_stockinventaris = $this->db->query($sql_stockinventaris, [ + $stockID, + $param['ruanganID'], + $noBarcode, + $user['M_BranchID'], + $user['M_UserID'] + ]); + if (!$que_stockinventaris) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert into table stock inventaris"); + exit; + } + + # insert each inventory handover detail # + $sql_insert_handover_detail = "INSERT INTO asset_handover_detail( + AssetHandoverDetailAssetHandoverID, + AssetHandoverDetailReceiveOrderPoDetailID, + AssetHandoverDetailT_BarcodeBarangID, + AssetHandoverDetailM_ItemID, + AssetHandoverDetailIsActive, + AssetHandoverDetailCreated, + AssetHandoverDetailUserID + ) VALUES(?,?,?,?,'Y',NOW(),?)"; + $que_insert_handover_detail = $this->db->query($sql_insert_handover_detail, [ + $handoverID, + $item['ReceiveOrderPoDetailID'], + $barcodeID, + $item['ReceiveOrderPoItemID'], + $user['M_UserID'] + ]); + if (!$que_insert_handover_detail) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert asset handover detail"); + exit; + } + } + } + + # check if all received inventaris are all handed over # + $sql_cek_allhanded = "SELECT + rod.ReceiveOrderPoDetailID, + CASE + WHEN COALESCE(ahd_count.InsertedQty, 0) = rod.ReceiveOrderPoDetailQty THEN 'Y' + ELSE 'N' + END AS isHandoverDone + FROM receive_order_po_detail rod + JOIN m_item mi ON mi.M_ItemID = rod.ReceiveOrderPoItemID + LEFT JOIN ( + SELECT + AssetHandoverDetailReceiveOrderPoDetailID, + COUNT(*) AS InsertedQty + FROM asset_handover_detail ahd + JOIN asset_handover ah + ON ahd.AssetHandoverDetailAssetHandoverID = ah.AssetHandoverID + AND ah.AssetHandoverIsActive = 'Y' + WHERE ahd.AssetHandoverDetailIsActive = 'Y' + AND ah.AssetHandoverReceiveOrderPoID = ? + GROUP BY AssetHandoverDetailReceiveOrderPoDetailID + ) ahd_count + ON ahd_count.AssetHandoverDetailReceiveOrderPoDetailID = rod.ReceiveOrderPoDetailID + WHERE rod.ReceiveOrderPoDetailReceiveOrderPoID = ? + AND rod.ReceiveOrderPoDetailIsActive = 'Y'"; + $que_cek_allhanded = $this->db->query($sql_cek_allhanded, [ + $param['receiveOrderPoID'], + $param['receiveOrderPoID'] + ]); + if (!$que_cek_allhanded) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] cek data all handed over"); + exit; + } + $cek_allhanded = $que_cek_allhanded->result_array(); + + $isAllHanded = count($cek_allhanded) > 0; + foreach ($cek_allhanded as $key => $value) { + if ($value['isHandoverDone'] != 'Y') { + $isAllHanded = false; + break; + } + } + + # update status handover di receive order po # + if ($isAllHanded) { + $sql_update_ro = "UPDATE receive_order_po SET + ReceiveOrderPoIsHandover = 'Y', + ReceiveOrderPoLastUpdated = NOW(), + ReceiveOrderPoLastUpdatedUserID = ? + WHERE ReceiveOrderPoID = ?"; + $que_update_ro = $this->db->query($sql_update_ro, [ + $user['M_UserID'], + $param['receiveOrderPoID'] + ]); + if (!$que_update_ro) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] update status handover di RO"); + exit; + } + } + + $this->db->trans_commit(); + $this->sys_ok("[Success] Berhasil menyimpan data serah terima barang"); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function saveFiles() + { + try { + $this->db->trans_begin(); + $param = $this->sys_input; + $user = $this->sys_user; + + + $path = "/home/one/project/accone/one-media/order-inventaris/"; + $year = date('Y'); + $targetpath = $path . $year . "/"; + + if (!is_dir($targetpath)) { + mkdir($targetpath, 0755, true); + } + + $config['upload_path'] = $targetpath; + $config['allowed_types'] = 'jpg|jpeg|png'; + $config['max_size'] = '10000'; + $count = count($_FILES['files']['name']); + $this->load->library('upload', $config); + + $error = []; + for ($i = 0; $i < $count; $i++) { + if (!empty($_FILES['files']['name'][$i])) { + $_FILES['file']['name'] = $_FILES['files']['name'][$i]; + $_FILES['file']['type'] = $_FILES['files']['type'][$i]; + $_FILES['file']['tmp_name'] = $_FILES['files']['tmp_name'][$i]; + $_FILES['file']['error'] = $_FILES['files']['error'][$i]; + $_FILES['file']['size'] = $_FILES['files']['size'][$i]; + + $ext = pathinfo($_FILES['name'][$i], PATHINFO_EXTENSION); + $random_str = bin2hex(random_bytes(4)); + $new_filename = 'IVT' . $random_str . '_' . $param['receiveOrderPoNumber'] . $ext; + $config['file_name'] = $new_filename; + + $this->upload->initialize($config); + + if ($this->upload->do_upload('file')) { + $uploadData = $this->upload->data(); + $filename = $uploadData['file_name']; + + $sql_insert_file = "INSERT INTO receive_order_po_document ( + ReceiveOrderPoDocumentReceiveOrderPoID, + ReceiveOrderPoDocumentDate, + ReceiveOrderPoDocumentFile, + ReceiveOrderPoDocumentIsActive, + ReceiveOrderPoDocumentCreated, + ReceiveOrderPoDocumentUserID + ) VALUES(?,NOW(),?,'Y',NOW(),?)"; + $que_insert_file = $this->db->query($sql_insert_file, [ + $param['receiveOrderPoID'], + $filename, + $param['userId'] + ]); + if (!$que_insert_file) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert receive order po files"); + exit; + } + } else { + $this->db->trans_rollback(); + $error[] = $this->upload->display_errors(); + $this->sys_error("[Error] " . $error); + exit; + } + } + } + + $this->db->trans_commit(); + $this->sys_ok("[Success] Berhasil upload file"); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + function getBarcodes() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + + $this->db->trans_begin(); + $param = $this->sys_input; + $user = $this->sys_user; + + $sql = "SELECT + T_BarcodeBarangID as id, + T_BarcodeBarangNumber, + M_ItemDesc, + M_BranchName, + M_RuanganName, + 'N' as chex + FROM t_barcode_barang + JOIN m_item ON M_ItemID = T_BarcodeBarangM_ItemID + JOIN m_branch ON M_BranchID = T_BarcodeBarangM_BranchID + LEFT JOIN m_ruangan ON M_RuanganID = T_BarcodeBarangM_RuanganID + WHERE T_BarcodeBarangReceiveOrderPoID = ? + AND T_BarcodeBarangIsActive = 'Y' + ORDER BY T_BarcodeBarangID"; + $que = $this->db->query($sql, [$param['ROID']]); + if (!$que) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get barcodes"); + exit; + } + + $barcodes = $que->result_array(); + if ($barcodes) { + foreach ($barcodes as $k => $v) { + if ($v['chex'] == 'N') + $barcodes[$k]['chex'] = false; + else + $barcodes[$k]['chex'] = true; + } + } + $this->db->trans_commit(); + $this->sys_ok($barcodes); + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } + + private function insertJurnalPerItem($user, $detail_ro) {} + + private function generatePurchaseInvoice($user, $ROID, $grni, $discpo, $shipping) + { + + # generate nomor purchase invoice # + $numPI = $this->generateNoLogistik($user, 'PI'); + + # prepare data # + $sql_data_ro = "SELECT * FROM receive_order_po WHERE ReceiveOrderPoID = ?"; + $que_data_ro = $this->db->query($sql_data_ro, [$ROID]); + if (!$que_data_ro) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get data RO to generate PI"); + exit; + } + $data_ro = $que_data_ro->row_array(); + + $sql_detail_ro = "SELECT + receive_order_po_detail.*, + M_ItemDesc, + PurchaseOrderSummaryDiscountType AS DiscountType, + PurchaseOrderSummaryDiscountRupiah AS DiscountRupiah, + PurchaseOrderSummaryDiscountPercent AS DiscountPercent, + PurchaseOrderSummaryDiscountAmount as DiscountPerItem + FROM receive_order_po_detail + JOIN m_item ON M_ItemID = ReceiveOrderPoItemID AND M_ItemIsActive = 'Y' + JOIN purchase_order_summary ON ReceiveOrderPoDetailPurchaseOrderSummaryID = PurchaseOrderSummaryID + WHERE ReceiveOrderPoDetailIsActive = 'Y' + AND ReceiveOrderPoDetailReceiveOrderPoID = ?"; + $que_detail_ro = $this->db->query($sql_detail_ro, [$ROID]); + if (!$que_detail_ro) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] get data detail RO to generate PI"); + exit; + } + $detail_ro = $que_detail_ro->result_array(); + + $due_date = new DateTime($data_ro['ReceiveOrderPoIDate']); + $due_date->add(new DateInterval('P30D')); + $due_date = $due_date->format('Y-m-d'); + + $subtotal = round(($grni - $shipping) + $discpo, 2); + + # insert header purchase invoice # + $sql_insert_PI = "INSERT INTO supplier_invoice ( + SupplierInvoiceNumber, + SupplierInvoiceReceiveOrderPoID, + SupplierInvoiceDate, + SupplierInvoiceDueDate, + SupplierInvoiceSupplierID, + SupplierInvoiceRefNumber, + SupplierInvoiceDeliveryOrderNumber, + SupplierInvoiceSubTotal, + SupplierInvoiceDiscountPercent, + SupplierInvoiceDiscountAmount, + SupplierInvoiceTaxPercentPph, + SupplierInvoiceTaxAmountPph, + SupplierInvoiceTaxPercentPpn, + SupplierInvoiceTaxAmountPpn, + SupplierInvoiceShippingCost, + SupplierInvoiceGrandTotal, + SupplierInvoiceUnpaid, + SupplierInvoiceNote, + SupplierInvoiceReceiveDate, + SupplierInvoiceReceivedBy, + SupplierInvoiceCreatedUserID + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),?,?)"; + $que_insert_PI = $this->db->query($sql_insert_PI, [ + $numPI, + $data_ro['ReceiveOrderPoID'], + $data_ro['ReceiveOrderPoIDate'], + $due_date, + $data_ro['ReceiveOrderPoSupplierID'], + $data_ro['ReceiveOrderPoRefNumber'], + $data_ro['ReceiveOrderPoDONumber'], + $subtotal, + 0.00, + $discpo, + 0.00, + 0.00, + 0.00, + 0.00, + $shipping, + $grni, + $grni, + $data_ro['ReceiveOrderPoNote'], + $user['M_UserID'], + $user['M_UserID'] + ]); + if (!$que_insert_PI) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert header purchase invoice"); + exit; + } + $Pinvoice_ID = $this->db->insert_id(); + + # insert detail purchase invoice # + $sql_insert_detailPI = "INSERT INTO supplier_invoice_detail ( + SupplierInvoiceDetailSupplierInvoiceID, + SupplierInvoiceDetailPurchaseOrderID, + SupplierInvoiceDetailPurchaseOrderSummaryID, + SupplierInvoiceDetailReceiveOrderPoID, + SupplierInvoiceDetailReceiveOrderPoDetailID, + SupplierInvoiceDetailItemID, + SupplierInvoiceDetailItemUnitID, + SupplierInvoiceDetailDescription, + SupplierInvoiceDetailQty, + SupplierInvoiceDetailPrice, + SupplierInvoiceDetailDiscountPercent, + SupplierInvoiceDetailDiscountDiscountRupiah, + SupplierInvoiceDetailDiscountDiscountType, + SupplierInvoiceDetailDiscountPoProrata, + SupplierInvoiceDetailDiscountAmount, + SupplierInvoiceDetailTotal, + SupplierInvoiceDetailUnpaid, + SupplierInvoiceDetailCreatedUserID + ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + foreach ($detail_ro as $key => $item) { + $itemprice = doubleval($item['ReceiveOrderPoDetailPrice']) - doubleval($item['DiscountPerItem']); + $total_price = round($itemprice * intval($item['ReceiveOrderPoDetailQty']), 2); + + $que_insert_itemPI = $this->db->query($sql_insert_detailPI, [ + $Pinvoice_ID, + $item['ReceiveOrderPoDetailPurchaseOrderID'], + $item['ReceiveOrderPoDetailPurchaseOrderSummaryID'], + $item['ReceiveOrderPoDetailReceiveOrderPoID'], + $item['ReceiveOrderPoDetailID'], + $item['ReceiveOrderPoItemID'], + $item['ReceiveOrderPoItemUnitID'], + $item['M_ItemDesc'], + $item['ReceiveOrderPoDetailQty'], + $item['ReceiveOrderPoDetailPrice'], + $item['DiscountPercent'], + $item['DiscountRupiah'], + $item['DiscountType'], + $item['ReceiveOrderPoDetailDiskonPoProrata'], + $item['DiscountPerItem'], + $total_price, + $total_price, + $user['M_UserID'] + ]); + if (!$que_insert_itemPI) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] insert header purchase invoice"); + exit; + } + } + + # insert log activity # + $this->insertUserActivty($Pinvoice_ID, 'INV', 'CREATE', $user['M_UserID'], ''); + } + + private function insertLogReceiveOrderPo($id, $type, $dataBefore, $dataAfter, $userID, $desc = '') + { + $sql = "INSERT INTO acc_one_log.receive_order_po_log ( + ReceiveOrderPoLogReceiveOrderPoID, + ReceiveOrderPoLogType, + ReceiveOrderPoLogDesc, + ReceiveOrderPoLogJsonBefore, + ReceiveOrderPoLogJsonAfter, + ReceiveOrderPoLogUserID, + ReceiveOrderPoLogCreated + ) VALUES (?, ?, ?, ?, ?, ?, NOW())"; + $que = $this->db->query($sql, [ + $id, + $type, + $desc, + !empty($dataBefore) ? json_encode($dataBefore) : '', + !empty($dataAfter) ? json_encode($dataAfter) : '', + $userID + ]); + if (!$que) { + $this->db->trans_rollback(); + $this->sys_error_db("[Error] inserting log into insert LogReceiveOrderPo"); + exit; + } + } + + private function insertLogPoItemReceive($id, $type, $roID, $dataBefore, $dataAfter, $userID, $desc = '') + { + $sql = "INSERT INTO acc_one_log.po_item_receive_log ( + PoItemReceiveLogPoItemReceiveID, + PoItemReceiveLogReceiveOrderPoID, + PoItemReceiveLogType, + PoItemReceiveLogDesc, + PoItemReceiveLogJsonBefore, + PoItemReceiveLogJsonAfter, + PoItemReceiveLogUserID, + PoItemReceiveLogCreated + ) VALUES (?, ?, ?, ?, ?, ?, ?, NOW())"; + $que = $this->db->query($sql, [ + $id, + $roID, + $type, + $desc, + !empty($dataBefore) ? json_encode($dataBefore) : '', + !empty($dataAfter) ? json_encode($dataAfter) : '', + $userID + ]); + if (!$que) { + $this->sys_error_db("[Error] inserting log po item receive"); + $this->db->trans_rollback(); + exit; + } + } + + private function insertUserActivty($id, $typePL, $status, $userID, $desc = '') + { + $sql = "INSERT INTO user_activity ( + UserActivityCode, + UserActivityStatus, + UserActivityDescription, + UserActivityRefID, + UserActivityUserID, + UserActivityCreated + ) VALUES (?, ?, ?, ?, ?, NOW())"; + $que = $this->db->query($sql, [$typePL, $status, $desc, $id, $userID]); + if (!$que) { + $this->sys_error_db("[Error] inserting user activity"); + $this->db->trans_rollback(); + exit; + } + } + + private function formatRupiah($data) + { + $data = str_replace(',', '.', $data); + if (!is_numeric($data)) { + return 'Input tidak valid'; + } + + $data = (float)$data; + $data = round($data, 2); + + if (fmod($data, 1) == 0.0) { + $formatted = number_format($data, 0, ',', '.'); + } else { + $formatted = number_format($data, 2, ',', '.'); + } + return 'Rp ' . $formatted; + } + + function template() + { + try { + if (!$this->isLogin) { + $this->sys_error("invalid token"); + exit; + } + } catch (Exception $exc) { + $message = $exc->getMessage(); + $this->sys_error($message); + } + } +}