<?php

class Receiveitempo extends MY_Controller
{
    var $db;

    public function index()
    {
        echo "Receive item po API";
    }

    public function __construct()
    {
        parent::__construct();
    }



    function getSupplier()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
                exit;
            }

            $payload = $this->sys_input;
            $userId = $this->sys_user["M_UserID"];

            $search = '%%';
            if (isset($payload['search'])) {
                $search = trim($payload["search"]);
                if ($search != "") {
                    $search = '%' . $search . '%';
                } else {
                    $search = '%%';
                }
            }

            $sql = "SELECT SupplierID,
                    SupplierCode,
                    SupplierName
                    FROM supplier
                    WHERE SupplierIsActive = 'Y'
                    AND SupplierName LIKE '{$search}'
                    ORDER BY SupplierName ASC ";
            $qry = $this->db->query($sql, []);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("select supplier", $this->db);;
                exit;
            }

            $rows = $qry->result_array();

            $result = array(
                "records" => $rows,
                "sql" => $this->db->last_query()
            );

            $this->sys_ok($rows);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }
    function getPurchaseOrder()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
                exit;
            }

            $payload = $this->sys_input;
            $userId = $this->sys_user["M_UserID"];
            $regionalID = $this->sys_user["S_RegionalID"];
            $branchID = $this->sys_user["M_BranchID"] ?? 0; // = 0 jika user regional
            $supplierID = $payload['SupplierID'];
            $warehouseID = $payload['WarehouseID'];

            $search = '%%';
            if (isset($payload['search'])) {
                $search = trim($payload["search"]);
                if ($search != "") {
                    $search = '%' . $search . '%';
                } else {
                    $search = '%%';
                }
            }

            $sql = "SELECT 
                        GROUP_CONCAT(DISTINCT PurchaseOrderDetailWarehouseID) 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
                    JOIN warehouse
                        ON PurchaseOrderDetailWarehouseID = WarehouseID
                        AND WarehouseM_BranchID = ?
                    WHERE WarehouseS_RegionalID = ?
                    AND PurchaseOrderSupplierID = ?
                    AND PurchaseOrderStatus = 'Approved'
                    -- Tambah filter agar tidak bisa add Jasa
                    AND PurchaseOrderItemCategoryID != 4
                    AND PurchaseOrderNumber LIKE ?
                    GROUP BY PurchaseOrderID
                    LIMIT 50";
            $qry = $this->db->query($sql, [$branchID, $regionalID, $supplierID, $search]);
            if (!$qry) {

                $this->sys_error_db("select po", $this->db);;
                exit;
            }
            $rows = $qry->result_array();
            $this->sys_ok($rows);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function getWarehouse()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
                exit;
            }

            $payload = $this->sys_input;
            $user = $this->sys_user;
            $userId = $this->sys_user["M_UserID"];
            $regionalId =  $this->sys_user["S_RegionalID"];
            $sqlWhere = "";

            if ($user['M_UserLocationFlag'] == "R") {
                $sqlWhere = "AND WarehouseType = 'R'";
            }
            if ($user['M_UserLocationFlag'] == "RB" || $user['M_UserLocationFlag'] == "B") {
                $sqlWhere = "AND WarehouseType = 'B' AND WarehouseM_BranchID = {$user['M_BranchID']}";
            }

            $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'
                    $sqlWhere
                    ORDER BY WarehouseName ASC ";
            $qry = $this->db->query($sql, [$regionalId]);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("select warehouse", $this->db);;
                exit;
            }

            $rows = $qry->result_array();

            $result = array(
                "records" => $rows,
                "sql" => $this->db->last_query()
            );

            $this->sys_ok($rows);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }
    function getItem()
    {
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $user["M_UserID"];
        $POID = $prm["POID"];
        $warehouseID = $prm["WarehouseID"];
        $regionalId = $user["S_RegionalID"];
        $branchID = $user["M_BranchID"];
        $userLogin = $user["M_UserLocationFlag"];
        $sqlTambahan = "";

        $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,
                '' as batchNo,
                '' as itemEd
            FROM po_item_receive
            JOIN purchase_order
                ON PoItemReceivePurchaseOrderID = PurchaseOrderID
                AND PurchaseOrderIsActive = 'Y'
                AND PoItemReceiveIsActive = 'Y'
                AND PurchaseOrderID = ?
                AND (PoItemReceiveQty - PoItemReceiveQtyReceived) > 0
            JOIN warehouse
                ON PoItemReceiveWarehouseID = WarehouseID
                AND WarehouseID = ?
            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";
        $qry = $this->db->query($sql, [$POID, $warehouseID]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("select item ", $this->db);;
            exit;
        }
        $dataItem = $qry->result_array();
        $this->sys_ok($dataItem);
    }
    function getItemUpdate()
    {
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $id = $prm["id"];
        $sql = "SELECT  
                ReceiveOrderPoDetailID, 
                CONCAT(ReceiveOrderPoDetailPoItemReceiveID,',',ReceiveOrderPoDetailID) as keyID,
                ReceiveOrderPoDetailPoItemReceiveID PoItemReceiveID,
                PurchaseOrderNumber,
                PurchaseOrderShippingCost,
                PurchaseOrderShippingCostStatus,
                ReceiveOrderPoDetailPurchaseOrderID PoItemReceivePurchaseOrderID,
                ReceiveOrderPoDetailPurchaseOrderSummaryID PoItemReceivePurchaseOrderSummaryID,
                ReceiveOrderPoDetailPurchaseOrderDetailID 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,
                ReceiveOrderPoDetailQty as tmpQty,
                PoItemReceiveQty - PoItemReceiveQtyReceived AS qtyRest,
                ReceiveOrderPoDetailQty,
                PoItemReceivePrice,
                'Y' as alreadySave,
                ReceiveOrderPoDetailBatchNo batchNo,
                ReceiveOrderPoDetailEd itemEd
                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 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
                WHERE ReceiveOrderPoDetailReceiveOrderPoID = ?
                AND ReceiveOrderPoDetailIsActive = 'Y'";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("select item ", $this->db);;
            exit;
        }
        $dataItem = $qry->result_array();
        $this->sys_ok($dataItem);
    }

    function getItemold()
    {
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $userId = $this->sys_user["M_UserID"];
        $POID = $prm["POID"];
        $regionalId = $prm["regionalId"];
        // echo $prm;

        $sql = "SELECT * FROM purchase_order WHERE PurchaseOrderID = ?";
        $qry = $this->db->query($sql, [$POID]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("select PO", $this->db);;
            exit;
        }
        $dataPO = $qry->row_array();

        // single berdasarkan summary 
        // multiple berdasarkan detail

        $sql = "SELECT 
                PurchaseOrderWarehouseType,
                PurchaseOrderWarehouseID,
                PurchaseOrderDetailWarehouseID,
                WarehouseID as warehouseID,
                CASE
                    WHEN WarehouseType = 'B' THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName) 
                    WHEN WarehouseType = 'R' THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName) 
                    ELSE ''
                END warehouseName,
                CASE
                    WHEN PurchaseOrderWarehouseType = 'Single' THEN PurchaseOrderSummaryQty - PurchaseOrderSummaryQtyReceived
                    WHEN PurchaseOrderWarehouseType  = 'Multiple' THEN (ConvertQuantityToPurchasedItemUnit(PurchaseOrderDetailItemID, PurchaseOrderDetailItemUnitID,
                        PurchaseOrderDetailQty)) - (ConvertQuantityToPurchasedItemUnit(PurchaseOrderDetailItemID, PurchaseOrderDetailItemUnitID,
                        PurchaseOrderDetailQtyReceived))
                END as qtyRest, -- qty sisa barang yang sudah di terima
                CASE
                    WHEN PurchaseOrderWarehouseType = 'Single' THEN PurchaseOrderSummaryQty 
                    WHEN PurchaseOrderWarehouseType  = 'Multiple' THEN ConvertQuantityToPurchasedItemUnit(PurchaseOrderDetailItemID, PurchaseOrderDetailItemUnitID,
                        PurchaseOrderDetailQty)
                END as qty, -- qty asli 
                CASE
                    WHEN PurchaseOrderWarehouseType = 'Single' THEN PurchaseOrderSummaryQty 
                    WHEN PurchaseOrderWarehouseType  = 'Multiple' THEN PurchaseOrderDetailQty
                END as qtyNotConvert,
                CASE
                    WHEN PurchaseOrderWarehouseType = 'Single' THEN PurchaseOrderSummaryQtyReceived
                    WHEN PurchaseOrderWarehouseType  = 'Multiple' THEN (ConvertQuantityToPurchasedItemUnit(PurchaseOrderDetailItemID, PurchaseOrderDetailItemUnitID,
                        PurchaseOrderDetailQtyReceived))
                END as qtyReceived,
                CASE
                    WHEN PurchaseOrderWarehouseType = 'Single' THEN PurchaseOrderSummaryQtyReceived
                    WHEN PurchaseOrderWarehouseType  = 'Multiple' THEN PurchaseOrderDetailQtyReceived
                END as qtyReceivedNotConvert,
                PurchaseOrderID,
                PurchaseOrderDate,
                PurchaseOrderNumber,
                PurchaseOrderSupplierID,
                SupplierName,
                PurchaseOrderStatus,
                PurchaseOrderSummaryID,
                PurchaseOrderSummaryQty,
                PurchaseOrderSummaryQtyReceived,
                ism.M_ItemID as summaryItemID,
                ism.M_ItemCode as summaryItemCode,
                ism.M_ItemDesc as summaryItemDesc,
                iusm.ItemUnitID as summaryItemUnitID,
                iusm.ItemUnitName as summaryItemUnitName,
                PurchaseOrderDetailID,
                PurchaseOrderDetailQty,
                PurchaseOrderDetailQtyReceived,
                idt.M_ItemID as detailItemID,
                idt.M_ItemCode as detailItemCode,
                idt.M_ItemDesc as detailItemDesc,
                iudt.ItemUnitID as detailItemUnitID,
                iudt.ItemUnitName as detailItemUnitName
                FROM purchase_order
                JOIN purchase_order_summary
                ON PurchaseOrderID = PurchaseOrderSummaryPurchaseOrderID
                AND PurchaseOrderSummaryIsActive = 'Y'
                AND PurchaseOrderSummaryPurchaseOrderID = ?
                JOIN purchase_order_detail
                ON PurchaseOrderID = PurchaseOrderDetailPurchaseOrderID
                AND PurchaseOrderSummaryID = PurchaseOrderDetailPurchaseSummaryID
                AND PurchaseOrderDetailIsActive = 'Y'
                JOIN supplier
                ON PurchaseOrderSupplierID = SupplierID
                JOIN m_item ism
                ON PurchaseOrderSummaryItemID = ism.M_ItemID
                JOIN itemunit iusm
                ON PurchaseOrderSummaryItemUnitID = iusm.ItemUnitID
                JOIN m_item idt
                ON PurchaseOrderDetailItemID = idt.M_ItemID
                JOIN itemunit iudt
                ON PurchaseOrderDetailItemUnitID = iudt.ItemUnitID
                JOIN warehouse 
                ON (
                    CASE 
                        WHEN PurchaseOrderWarehouseType = 'Single' THEN PurchaseOrderWarehouseID = WarehouseID
                        WHEN PurchaseOrderWarehouseType  = 'Multiple' THEN PurchaseOrderDetailWarehouseID = WarehouseID
                    END
                )
                JOIN s_regional                 
                ON WarehouseS_RegionalID = S_RegionalID 
                LEFT JOIN m_branch 
                ON WarehouseM_BranchID = M_BranchID
                WHERE 
                    CASE 
                        WHEN PurchaseOrderWarehouseType = 'Single' THEN (PurchaseOrderSummaryQty - PurchaseOrderSummaryQtyReceived) > 0
                        WHEN PurchaseOrderWarehouseType  = 'Multiple' THEN ((ConvertQuantityToPurchasedItemUnit(PurchaseOrderDetailItemID, PurchaseOrderDetailItemUnitID,
                        PurchaseOrderDetailQty)) - (ConvertQuantityToPurchasedItemUnit(PurchaseOrderDetailItemID, PurchaseOrderDetailItemUnitID,
                        PurchaseOrderDetailQtyReceived))) > 0
                    END ";

        $qry = $this->db->query($sql, [$POID]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("select item ", $this->db);;
            exit;
        }
        $dataItem = $qry->result_array();
        $newItem = [];
        if ($dataPO['PurchaseOrderWarehouseType'] == 'Single') {
            foreach ($dataItem as $key => $item) {
                $search_id = $item['PurchaseOrderSummaryID'];
                $ids = array_column($newItem, 'PurchaseOrderSummaryID');
                $index = array_search($search_id, $ids);
                if (in_array($search_id, $ids) && $index !== false) {
                    $newItem[$index]['detail'][] = $item;
                } else {

                    $item['itemID'] = $item['summaryItemID'];
                    $item['itemCode'] = $item['summaryItemCode'];
                    $item['itemDesc'] = $item['summaryItemDesc'];
                    $item['itemUnitID'] = $item['summaryItemUnitID'];
                    $item['itemUnitName'] = $item['summaryItemUnitName'];
                    $item['detail'] = [$item];
                    $newItem[] = $item;
                }
            }
        }
        if ($dataPO['PurchaseOrderWarehouseType'] == 'Multiple') {
            foreach ($dataItem as $key => $item) {


                $item['itemID'] = $item['summaryItemID'];
                $item['itemCode'] = $item['summaryItemCode'];
                $item['itemDesc'] = $item['summaryItemDesc'];
                $item['itemUnitID'] = $item['summaryItemUnitID'];
                $item['itemUnitName'] = $item['summaryItemUnitName'];
                $item['detail'] = [];
                $newItem[] = $item;
            }
        }
        $this->sys_ok($newItem);
    }

    public function saveRo()
    {
        // $this->db->trans_commit();
        // $this->db->trans_rollback();
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $this->sys_user["M_UserID"];

        $sql = "SELECT `fn_numbering`('RO') AS RO";
        $qry = $this->db->query($sql, []);



        if (!$qry) {
            $this->sys_error_db("purchase order insert error", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $numbering = $qry->row_array()["RO"];

        $sql = "INSERT INTO `receive_order_po` (
                `ReceiveOrderPoNumber`,
                `ReceiveOrderPoSupplierID`,
                `ReceiveOrderPoIDate`,
                `ReceiveOrderPoWarehouseID`,
                `ReceiveOrderPoM_BranchCode`,
                `ReceiveOrderPoS_RegionalID`,
                `ReceiveOrderShippingCostAmount`,
                `ReceiveOrderPoNote`,
                `ReceiveOrderPoRefNumber`,
                `ReceiveOrderPoCreatedUserID`
            ) VALUES (?,?,?,?,?,?,?,?,?,?);";
        $qry = $this->db->query($sql, [
            $numbering,
            $prm['selectedSupplier']['SupplierID'],
            $prm['date'],
            $prm['selectedWarehouse']['WarehouseID'],
            $user['M_BranchCode'],
            $user['S_RegionalID'],
            $prm['shippingCost'],
            $prm['note'],
            $prm['refNumber'],
            $userId
        ]);
        if (!$qry) {
            $this->sys_error_db("Error insert receive oder", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $roID = $this->db->insert_id();
        $descDetail = [];
        foreach ($prm['detail'] as $key => $item) {
            $sql = "SELECT * FROM po_item_receive WHERE PoItemReceiveID = ?";
            $qry = $this->db->query($sql, [
                $item['PoItemReceiveID'],
            ]);
            if (!$qry) {
                $this->sys_error_db("Error cek data", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $cek = $qry->row_array();

            if ($cek['PoItemReceiveIsActive'] == 'N') {
                $this->sys_error("Item {$item['M_ItemDesc']} sudah terhapus");
                $this->db->trans_rollback();
                exit;
            }
            if ($cek['PoItemReceiveQty'] == $cek['PoItemReceiveQtyReceived']) {
                $this->sys_error("Item {$item['M_ItemDesc']} sudah diterima semuanya");
                $this->db->trans_rollback();
                exit;
            }
            if (intval($item['qty']) > intval($cek['PoItemReceiveQty'])) {
                $this->sys_error("Jumlah item {$item['M_ItemDesc']} yang tersedia sudah berubah silahkan ulangi pilih item");
                $this->db->trans_rollback();
                exit;
            }

            $sql = "INSERT INTO `receive_order_po_detail` (
                    `ReceiveOrderPoDetailReceiveOrderPoID`,
                    `ReceiveOrderPoDetailPurchaseOrderID`,
                    `ReceiveOrderPoDetailPurchaseOrderSummaryID`,
                    `ReceiveOrderPoDetailPurchaseOrderDetailID`,
                    `ReceiveOrderPoDetailPoItemReceiveID`,
                    `ReceiveOrderPoDetailQty`,
                    `ReceiveOrderPoDetailPrice`,
                    `ReceiveOrderPoDetailTotal`,
                    `ReceiveOrderPoDetailCreatedUserID`,
                    `ReceiveOrderPoItemID`,
                    `ReceiveOrderPoItemUnitID`,
                    ReceiveOrderPoDetailBatchNo,
                    ReceiveOrderPoDetailEd
                ) VALUES (
                    ?, 
                    ?,  
                    ?,  
                    ?,  
                    ?,  
                    ?,  
                    ?, 
                    ?,
                    ?,
                    ?,
                    ?,
                    ?,
                    ?
                );";
            $qry = $this->db->query($sql, [
                $roID,
                $item['PoItemReceivePurchaseOrderID'],
                $item['PoItemReceivePurchaseOrderSummaryID'],
                $item['PoItemReceivePurchaseOrderDetailID'],
                $item['PoItemReceiveID'],
                $item['qty'],
                $item['PoItemReceivePrice'],
                (doubleval($item['PoItemReceivePrice']) * intval($item['qty'])),
                $userId,
                $item['M_ItemID'],
                $item['ItemUnitID'],
                $item['batchNo'],
                $item['itemEd'],
            ]);
            if (!$qry) {
                $this->sys_error_db("Error receive order detail", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $roDetailID =  $this->db->insert_id();
            $descDetail[] = "- ADD {$item['M_ItemDesc']} {$item['qty']} {$item['ItemUnitName']} nomor batch {$item['WarehouseName']}";


            $jsonBefore = $this->getDataPoItemReceive($item['PoItemReceiveID']);
            $sql = "UPDATE `po_item_receive`
                    SET 
                        `PoItemReceiveQtyReceived` = ?, 
                        `PoItemReceiveUpdatedUserID` = ?
                    WHERE `PoItemReceiveID` = ?;";
            $qry = $this->db->query($sql, [
                (intval($cek['PoItemReceiveQtyReceived']) + intval($item['qty'])),
                $userId,
                $item['PoItemReceiveID'],
            ]);
            if (!$qry) {
                $this->sys_error_db("Error update item receive", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $jsonAfter = $this->getDataPoItemReceive($item['PoItemReceiveID']);
            $descItem = "Diterima {$item['M_ItemDesc']} sejumlah {$item['qty']} {$item['ItemUnitName']} di RO nomor {$numbering} *RO belum di konfirmasi";
            $this->insertLogPoItemReceive(
                $item['PoItemReceiveID'],
                'UPDATE',
                $roID,
                $jsonBefore,
                $jsonAfter,
                $userId,
                $descItem
            );
        }
        $jsonROAfter = $this->getDataReceiveOrderPO($roID);
        $this->insertLogReceiveOrderPo(
            $roID,
            'ADD',
            '',
            $jsonROAfter,
            $userId,
            implode("\n", $descDetail)
        );
        $this->insertUserActivty($roID, 'ADD', $userId, implode("\n", $descDetail));
        $this->db->trans_commit();
        $this->sys_ok("Berhasil terima barang {$numbering} pada cabang {$user['M_BranchCode']}");
    }
    public function updateRoHeader()
    {
        // $this->db->trans_commit();
        // $this->db->trans_rollback();
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $this->sys_user["M_UserID"];
        $ro = $prm['ro'];
        $roID = $ro['ReceiveOrderPoID'];


        $jsonROBefore = $this->getDataReceiveOrderPO($roID);
        $sql = "UPDATE `receive_order_po` SET 
                `ReceiveOrderPoIDate` = ?,
                `ReceiveOrderShippingCostAmount` = ?,
                `ReceiveOrderPoNote` = ?,
                `ReceiveOrderPoRefNumber` = ?,
                `ReceiveOrderPoLastUpdatedUserID` = ?
            WHERE ReceiveOrderPoID = ?;";
        $qry = $this->db->query($sql, [
            $prm['date'],
            $prm['shippingCost'],
            $prm['note'],
            $prm['refNumber'],
            $userId,
            $roID
        ]);
        if (!$qry) {
            $this->sys_error_db("Error update receive oder", $this->db);
            $this->db->trans_rollback();
            exit;
        }

        $jsonROAfter = $this->getDataReceiveOrderPO($roID);
        $desc = "Update data Ro {$ro['ReceiveOrderPoNumber']}";
        $descDetail = [];
        if ($jsonROBefore['ReceiveOrderPoIDate'] != $jsonROAfter['ReceiveOrderPoIDate']) {
            $descDetail[] = "- Perubahan tanggal dari {$jsonROBefore['ReceiveOrderPoIDate']} menjadi {$jsonROAfter['ReceiveOrderPoIDate']}";
        }
        if ($jsonROBefore['ReceiveOrderPoNote'] != $jsonROAfter['ReceiveOrderPoNote']) {
            $descDetail[] = "- Perubahan catatan dari '{$jsonROBefore['ReceiveOrderPoNote']}' menjadi '{$jsonROAfter['ReceiveOrderPoNote']}'";
        }
        if ($jsonROBefore['ReceiveOrderPoRefNumber'] != $jsonROAfter['ReceiveOrderPoRefNumber']) {
            $descDetail[] = "- Perubahan nomor referensi dari '{$jsonROBefore['ReceiveOrderPoRefNumber']}' menjadi '{$jsonROAfter['ReceiveOrderPoRefNumber']}'";
        }
        if ($jsonROBefore['ReceiveOrderShippingCostAmount'] != $jsonROAfter['ReceiveOrderShippingCostAmount']) {
            $bfr = $this->formatRupiah($jsonROBefore['ReceiveOrderShippingCostAmount']);
            $aftr = $this->formatRupiah($jsonROAfter['ReceiveOrderShippingCostAmount']);
            $descDetail[] = "- Perubahan biaya ekspedisi dari {$bfr} menjadi {$aftr}";
        }
        if (count($descDetail) == 0) {
            $descDetail[] = '* user menyimpan data namun tidak ada perubahan';
        }
        $this->insertLogReceiveOrderPo(
            $roID,
            'UPDATE HEADER',
            $jsonROBefore,
            $jsonROAfter,
            $userId,
            $desc . "\n" . implode("\n", $descDetail)
        );
        $this->insertUserActivty($roID, 'UPDATE HEADER', $userId, $desc . "\n" . implode("\n", $descDetail));
        $this->db->trans_commit();
        $this->sys_ok("Berhasil update header {$ro['ReceiveOrderPoNumber']}");
    }

    function addItem()
    {
        // $this->db->trans_commit();
        // $this->db->trans_rollback();
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $this->sys_user["M_UserID"];
        $detail = $prm['detail'];
        $ro = $prm['ro'];
        $roID = $ro['ReceiveOrderPoID'];

        $sql = "SELECT * FROM receive_order_po WHERE ReceiveOrderPoID = ?";
        $qry = $this->db->query($sql, [
            $ro['ReceiveOrderPoID'],
        ]);
        if (!$qry) {
            $this->sys_error_db("Error cek order receive", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $cek = $qry->row_array();

        if ($cek['ReceiveOrderPoConfirmed'] == 'Y') {
            $this->sys_error("Penerimaan barang sudah dikonfirmasi");
            $this->db->trans_rollback();
            exit;
        }


        $jsonROBefore = $this->getDataReceiveOrderPO($roID);
        $descDetail = [];
        foreach ($detail as $key => $item) {
            //insert
            $sql = "SELECT * FROM po_item_receive WHERE PoItemReceiveID = ?";
            $qry = $this->db->query($sql, [
                $item['PoItemReceiveID'],
            ]);
            if (!$qry) {
                $this->sys_error_db("Error cek data", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $cekDetail = $qry->row_array();

            if ($cekDetail['PoItemReceiveIsActive'] == 'N') {
                $this->sys_error("Item {$item['M_ItemDesc']} sudah terhapus");
                $this->db->trans_rollback();
                exit;
            }
            if ($cekDetail['PoItemReceiveQty'] == $cekDetail['PoItemReceiveQtyReceived']) {
                $this->sys_error("Item {$item['M_ItemDesc']} sudah diterima semuanya");
                $this->db->trans_rollback();
                exit;
            }
            if (intval($item['qty']) > intval($cekDetail['PoItemReceiveQty'])) {
                $this->sys_error("Jumlah item {$item['M_ItemDesc']} yang tersedia sudah berubah silahkan ulangi pilih item");
                $this->db->trans_rollback();
                exit;
            }

            $sql = "INSERT INTO `receive_order_po_detail` (
                    `ReceiveOrderPoDetailReceiveOrderPoID`,
                    `ReceiveOrderPoDetailPurchaseOrderID`,
                    `ReceiveOrderPoDetailPurchaseOrderSummaryID`,
                    `ReceiveOrderPoDetailPurchaseOrderDetailID`,
                    `ReceiveOrderPoDetailPoItemReceiveID`,
                    `ReceiveOrderPoDetailQty`,
                    `ReceiveOrderPoDetailPrice`,
                    `ReceiveOrderPoDetailTotal`,
                    `ReceiveOrderPoDetailCreatedUserID`,
                    `ReceiveOrderPoItemID`,
                    `ReceiveOrderPoItemUnitID`
                ) VALUES (
                    ?, 
                    ?,  
                    ?,  
                    ?,  
                    ?,  
                    ?,  
                    ?, 
                    ?,
                    ?,
                    ?,
                    ?
                );";
            $qry = $this->db->query($sql, [
                $roID,
                $item['PoItemReceivePurchaseOrderID'],
                $item['PoItemReceivePurchaseOrderSummaryID'],
                $item['PoItemReceivePurchaseOrderDetailID'] ?? 0,
                $item['PoItemReceiveID'],
                $item['qty'],
                $item['PoItemReceivePrice'],
                (doubleval($item['PoItemReceivePrice']) * intval($item['qty'])),
                $userId,
                $item['M_ItemID'],
                $item['ItemUnitID'],
            ]);
            if (!$qry) {
                $this->sys_error_db("Error receive order detail", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $descDetail[] = "- ADD {$item['M_ItemDesc']} {$item['qty']} {$item['ItemUnitName']} {$item['WarehouseName']}";


            $jsonBefore = $this->getDataPoItemReceive($item['PoItemReceiveID']);

            $sql = "UPDATE `po_item_receive`
                    SET 
                        `PoItemReceiveQtyReceived` = ?, 
                        `PoItemReceiveUpdatedUserID` = ?
                    WHERE `PoItemReceiveID` = ?;";
            $qry = $this->db->query($sql, [
                (intval($cekDetail['PoItemReceiveQtyReceived']) + intval($item['qty'])),
                $userId,
                $item['PoItemReceiveID'],
            ]);
            if (!$qry) {
                $this->sys_error_db("Error update item receive", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $jsonAfter = $this->getDataPoItemReceive($item['PoItemReceiveID']);
            $descItem = "Diterima {$item['M_ItemDesc']} sejumlah {$item['qty']} {$item['ItemUnitName']} di RO nomor {$jsonROBefore['ReceiveOrderPoNumber']} *RO belum di konfirmasi";
            $this->insertLogPoItemReceive(
                $item['PoItemReceiveID'],
                'UPDATE',
                $roID,
                $jsonBefore,
                $jsonAfter,
                $userId,
                $descItem
            );
        }
        $jsonROAfter = $this->getDataReceiveOrderPO($roID);
        $this->insertLogReceiveOrderPo(
            $roID,
            'UPDATE',
            $jsonROBefore,
            $jsonROAfter,
            $userId,
            implode("\n", $descDetail)
        );
        $this->insertUserActivty($roID, 'UPDATE', $userId, implode("\n", $descDetail));
        $this->db->trans_commit();
        $this->sys_ok("Berhasil update item");
    }
    function formatRupiah($angka)
    {
        // Ganti koma ke titik agar jadi desimal yang valid
        $angka = str_replace(',', '.', $angka);

        // Validasi input
        if (!is_numeric($angka)) {
            return 'Input tidak valid';
        }

        // Konversi ke float
        $angka = (float)$angka;

        // Bulatkan ke 2 angka desimal
        $angka = round($angka, 2);

        // Cek apakah angka desimalnya nol
        if (fmod($angka, 1) == 0.0) {
            // Tanpa desimal
            $formatted = number_format($angka, 0, ',', '.');
        } else {
            // Dengan 2 angka desimal
            $formatted = number_format($angka, 2, ',', '.');
        }

        return 'Rp ' . $formatted;
    }

    function addItemOld()
    {
        // $this->db->trans_commit();
        // $this->db->trans_rollback();
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $this->sys_user["M_UserID"];
        $detail = $prm['detail'];
        $ro = $prm['ro'];
        $roID = $ro['ReceiveOrderPoID'];

        $sql = "SELECT * FROM receive_order_po WHERE ReceiveOrderPoID = ?";
        $qry = $this->db->query($sql, [
            $ro['ReceiveOrderPoID'],
        ]);
        if (!$qry) {
            $this->sys_error_db("Error cek order receive", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $cek = $qry->row_array();

        if ($cek['ReceiveOrderPoConfirmed'] == 'Y') {
            $this->sys_error("Penerimaan barang sudah dikonfirmasi");
            $this->db->trans_rollback();
            exit;
        }
        $sql = "SELECT * FROM receive_order_po_detail WHERE ReceiveOrderPoDetailReceiveOrderPoID = ? AND PoItemReceiveIsActive = 'Y'";
        $qry = $this->db->query($sql, [
            $roID,
        ]);
        if (!$qry) {
            $this->sys_error_db("Error cek order receive", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $oldDetail = $qry->result_array();

        $updatedID = [];
        foreach ($detail as $key => $item) {
            $sql = "SELECT * FROM receive_order_po_detail WHERE ReceiveOrderPoDetailPoItemReceiveID = ? AND PoItemReceiveIsActive = 'Y'";
            $qry = $this->db->query($sql, [
                $item['PoItemReceiveID'],
            ]);
            if (!$qry) {
                $this->sys_error_db("Error cek order receive", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $cekItem = $qry->row_array();

            if (empty($cekItem)) {
                //insert
                $sql = "SELECT * FROM po_item_receive WHERE PoItemReceiveID = ?";
                $qry = $this->db->query($sql, [
                    $item['PoItemReceiveID'],
                ]);
                if (!$qry) {
                    $this->sys_error_db("Error cek data", $this->db);
                    $this->db->trans_rollback();
                    exit;
                }
                $cekDetail = $qry->row_array();

                if ($cekDetail['PoItemReceiveIsActive'] == 'N') {
                    $this->sys_error("Item {$item['M_ItemDesc']} sudah terhapus");
                    $this->db->trans_rollback();
                    exit;
                }
                if ($cekDetail['PoItemReceiveQty'] == $cekDetail['PoItemReceiveQtyReceived']) {
                    $this->sys_error("Item {$item['M_ItemDesc']} sudah diterima semuanya");
                    $this->db->trans_rollback();
                    exit;
                }
                if (intval($item['qty']) > intval($cekDetail['PoItemReceiveQty'])) {
                    $this->sys_error("Jumlah item {$item['M_ItemDesc']} yang tersedia sudah berubah silahkan ulangi pilih item");
                    $this->db->trans_rollback();
                    exit;
                }

                $sql = "INSERT INTO `receive_order_po_detail` (
                    `ReceiveOrderPoDetailReceiveOrderPoID`,
                    `ReceiveOrderPoDetailPurchaseOrderID`,
                    `ReceiveOrderPoDetailPurchaseOrderSummaryID`,
                    `ReceiveOrderPoDetailPurchaseOrderDetailID`,
                    `ReceiveOrderPoDetailPoItemReceiveID`,
                    `ReceiveOrderPoDetailQty`,
                    `ReceiveOrderPoDetailPrice`,
                    `ReceiveOrderPoDetailTotal`,
                    `ReceiveOrderPoDetailCreatedUserID`,
                    `ReceiveOrderPoItemID`,
                    `ReceiveOrderPoItemUnitID`
                ) VALUES (
                    ?, 
                    ?,  
                    ?,  
                    ?,  
                    ?,  
                    ?,  
                    ?, 
                    ?,
                    ?,
                    ?,
                    ?
                );";
                $qry = $this->db->query($sql, [
                    $roID,
                    $item['PoItemReceivePurchaseOrderID'],
                    $item['PoItemReceivePurchaseOrderSummaryID'],
                    $item['PoItemReceivePurchaseOrderDetailID'] ?? 0,
                    $item['PoItemReceiveID'],
                    $item['qty'],
                    $item['PoItemReceivePrice'],
                    (doubleval($item['PoItemReceivePrice']) * intval($item['qty'])),
                    $userId,
                    $item['M_ItemID'],
                    $item['ItemUnitID'],
                ]);
                if (!$qry) {
                    $this->sys_error_db("Error receive order detail", $this->db);
                    $this->db->trans_rollback();
                    exit;
                }

                $sql = "UPDATE `po_item_receive`
                    SET 
                        `PoItemReceiveQtyReceived` = ?, 
                        `PoItemReceiveUpdatedUserID` = ?
                    WHERE `PoItemReceiveID` = ?;";
                $qry = $this->db->query($sql, [
                    (intval($cekDetail['PoItemReceiveQtyReceived']) + intval($item['qty'])),
                    $userId,
                    $item['PoItemReceiveID'],
                ]);
                if (!$qry) {
                    $this->sys_error_db("Error update item receive", $this->db);
                    $this->db->trans_rollback();
                    exit;
                }
            } else {
                $updatedID[] = $cekItem['ReceiveOrderPoDetailID'];
                $sql = "SELECT * FROM po_item_receive WHERE PoItemReceiveID = ?";
                $qry = $this->db->query($sql, [
                    $item['PoItemReceiveID'],
                ]);
                if (!$qry) {
                    $this->sys_error_db("Error cek data", $this->db);
                    $this->db->trans_rollback();
                    exit;
                }
                $cekDetail = $qry->row_array();

                // if ($cekDetail['PoItemReceiveIsActive'] == 'N') {
                //     $this->sys_error("Item {$item['M_ItemDesc']} sudah terhapus");
                //     $this->db->trans_rollback();
                //     exit;
                // }
                $newReceivedQty = intval($cekDetail['PoItemReceiveQtyReceived']) - intval($cekItem['ReceiveOrderPoDetailQty']);
                $newQtyRest = intval($cekDetail['PoItemReceiveQty']) - $newReceivedQty;
                // if ($cekDetail['PoItemReceiveQty'] == $cekDetail['PoItemReceiveQtyReceived']) {
                //     $this->sys_error("Item {$item['M_ItemDesc']} sudah diterima semuanya");
                //     $this->db->trans_rollback();
                //     exit;
                // }
                if (intval($item['qty']) > $newQtyRest) {
                    $this->sys_error("Jumlah item {$item['M_ItemDesc']} yang tersedia tidak memenuhi banyak penerimaan item");
                    $this->db->trans_rollback();
                    exit;
                }

                $sql = "UPDATE receive_order_po_detail 
                        SET 
                            ReceiveOrderPoDetailQty = ?, 
                            ReceiveOrderPoDetailTotal = ReceiveOrderPoDetailPrice * {$item['qty']}
                            ReceiveOrderPoDetailLastUpdatedUserID = ?, 
                            ReceiveOrderPoDetailLastUpdated = NOW() 
                        WHERE ReceiveOrderPoDetailID = ?;
                        ";
                $qry = $this->db->query($sql, [
                    $item['qty'],
                    $userId,
                    $cekItem['ReceiveOrderPoDetailID']
                ]);
                if (!$qry) {
                    $this->sys_error_db("Error update item", $this->db);
                    $this->db->trans_rollback();
                    exit;
                }
                $sql = "UPDATE `po_item_receive`
                    SET 
                        `PoItemReceiveQtyReceived` = ?, 
                        `PoItemReceiveUpdatedUserID` = ?
                    WHERE `PoItemReceiveID` = ?;";
                $qry = $this->db->query($sql, [
                    (intval($newReceivedQty) + intval($item['qty'])),
                    $userId,
                    $item['PoItemReceiveID'],
                ]);
                if (!$qry) {
                    $this->sys_error_db("Error update item receive", $this->db);
                    $this->db->trans_rollback();
                    exit;
                }
            }
        }
        $this->db->trans_commit();
        $this->sys_ok("Berhasil update item");
    }

    public function updateItem()
    {
        // $this->db->trans_commit();
        // $this->db->trans_rollback();
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $this->sys_user["M_UserID"];
        $detail = $prm['detail'];
        $ro = $prm['ro'];
        $roID = $ro['ReceiveOrderPoID'];
        $detail = $prm['detail'];
        $detailID = $detail['ReceiveOrderPoDetailID'];
        $jsonROBefore = $this->getDataReceiveOrderPO($roID);
        $sql = "SELECT * FROM receive_order_po_detail WHERE ReceiveOrderPoDetailID = ? ";
        $qry = $this->db->query($sql, [
            $detail['ReceiveOrderPoDetailID'],
        ]);
        if (!$qry) {
            $this->sys_error_db("Error cek order receive", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $cekItem = $qry->row_array();

        $sql = "SELECT * FROM po_item_receive WHERE PoItemReceiveID = ?";
        $qry = $this->db->query($sql, [
            $detail['PoItemReceiveID'],
        ]);
        if (!$qry) {
            $this->sys_error_db("Error cek data", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $cekDetail = $qry->row_array();

        // if ($cekDetail['PoItemReceiveIsActive'] == 'N') {
        //     $this->sys_error("Item {$item['M_ItemDesc']} sudah terhapus");
        //     $this->db->trans_rollback();
        //     exit;
        // }

        $newReceivedQty = intval($cekDetail['PoItemReceiveQtyReceived']) - intval($cekItem['ReceiveOrderPoDetailQty']);
        $newQtyRest = intval($cekDetail['PoItemReceiveQty']) - $newReceivedQty;
        // if ($cekDetail['PoItemReceiveQty'] == $cekDetail['PoItemReceiveQtyReceived']) {
        //     $this->sys_error("Item {$item['M_ItemDesc']} sudah diterima semuanya");
        //     $this->db->trans_rollback();
        //     exit;
        // }
        if (intval($detail['qty']) <= 0) {
            $this->sys_error("Jumlah qty {$detail['M_ItemDesc']} tidak sesuai");
            $this->db->trans_rollback();
            exit;
        }
        if (intval($detail['qty']) > $newQtyRest) {
            $this->sys_error("Jumlah item {$detail['M_ItemDesc']} yang tersedia tidak memenuhi banyak penerimaan item");
            $this->db->trans_rollback();
            exit;
        }

        $jsonBefore = $this->getDataPoItemReceive($detail['PoItemReceiveID']);
        $sql = "UPDATE receive_order_po_detail 
                        SET 
                            ReceiveOrderPoDetailQty = ?, 
                            ReceiveOrderPoDetailTotal = ReceiveOrderPoDetailPrice * {$detail['qty']},
                            ReceiveOrderPoDetailLastUpdatedUserID = ?, 
                            ReceiveOrderPoDetailLastUpdated = NOW() ,
                            ReceiveOrderPoDetailBatchNo = ?,
                            ReceiveOrderPoDetailEd = ?
                        WHERE ReceiveOrderPoDetailID = ?;
                        ";
        $qry = $this->db->query($sql, [
            $detail['qty'],
            $userId,
            $detail['batchNo'],
            $detail['itemEd'],
            $cekItem['ReceiveOrderPoDetailID']
        ]);
        if (!$qry) {
            $this->sys_error_db("Error update item", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $descDetail = 'UPDATE item detail';
        if (intval($detail['qty']) != intval($cekItem['ReceiveOrderPoDetailQty'])) {
            $descDetail = $descDetail . "\n" . " UPDATE ITEM qty {$detail['M_ItemDesc']} dari {$cekItem['ReceiveOrderPoDetailQty']} {$detail['ItemUnitName']} menjadi {$detail['qty']} {$detail['ItemUnitName']} {$detail['WarehouseName']}";
        }
        if ($cekItem['ReceiveOrderPoDetailBatchNo'] != $detail['batchNo']) {
            $descDetail = $descDetail . "\n" . "UPDATE nomor batch dari {$cekItem['ReceiveOrderPoDetailBatchNo']} menjadi {$detail['batchNo']}";
        }
        if ($cekItem['ReceiveOrderPoDetailEd'] != $detail['itemEd']) {
            $descDetail = $descDetail . "\n" . "UPDATE tanggal expaired {$cekItem['ReceiveOrderPoDetailEd']} menjadi {$detail['itemEd']}";
        }
        $jsonBefore = $this->getDataPoItemReceive($detail['PoItemReceiveID']);
        $sql = "UPDATE `po_item_receive`
                    SET 
                        `PoItemReceiveQtyReceived` = ?, 
                        `PoItemReceiveUpdatedUserID` = ?
                    WHERE `PoItemReceiveID` = ?;";
        $qry = $this->db->query($sql, [
            (intval($newReceivedQty) + intval($detail['qty'])),
            $userId,
            $detail['PoItemReceiveID'],
        ]);
        if (!$qry) {
            $this->sys_error_db("Error update item receive", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $jsonAfter = $this->getDataPoItemReceive($detail['PoItemReceiveID']);
        $dtlDesc = '';
        if (intval($cekItem['ReceiveOrderPoDetailQty']) > intval($detail['qty'])) {
            $nwQty = intval($cekItem['ReceiveOrderPoDetailQty']) - intval($detail['qty']);
            $dtlDesc = ", mengembalikan {$nwQty} {$detail['ItemUnitName']} ke jumlah item yang belum diterima ";
        }
        if (intval($detail['qty']) > intval($cekItem['ReceiveOrderPoDetailQty'])) {
            $nwQty = intval($detail['qty']) - intval($cekItem['ReceiveOrderPoDetailQty']);
            $dtlDesc = ", mengambil {$nwQty} {$detail['ItemUnitName']} dari jumlah item yang belum diterima ";
        }
        $descItem = "UPDATE ITEM qty {$detail['M_ItemDesc']} dari {$cekItem['ReceiveOrderPoDetailQty']} {$detail['ItemUnitName']} menjadi {$detail['qty']} {$detail['ItemUnitName']}{$dtlDesc} di RO nomor {$jsonROBefore['ReceiveOrderPoNumber']} *RO belum di konfirmasi";

        $this->insertLogPoItemReceive(
            $detail['PoItemReceiveID'],
            'UPDATE',
            $roID,
            $jsonBefore,
            $jsonAfter,
            $userId,
            $descItem
        );
        $jsonROAfter = $this->getDataReceiveOrderPO($roID);
        $this->insertLogReceiveOrderPo(
            $roID,
            'UPDATE DETAIL',
            $jsonROBefore,
            $jsonROAfter,
            $userId,
            $descDetail
        );
        $this->insertUserActivty($roID, 'UPDATE DETAIL', $userId, $descDetail);
        $this->db->trans_commit();
        $this->sys_ok("Berhasil updatw qty item {$detail['M_ItemDesc']}");
    }
    public function deleteItem()
    {
        // $this->db->trans_commit();
        // $this->db->trans_rollback();
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $this->sys_user["M_UserID"];
        $detail = $prm['detail'];
        $ro = $prm['ro'];
        $roID = $ro['ReceiveOrderPoID'];
        $detail = $prm['detail'];
        $detailID = $detail['ReceiveOrderPoDetailID'];
        $jsonROBefore = $this->getDataReceiveOrderPO($roID);
        $sql = "UPDATE receive_order_po_detail 
                        SET 
                            ReceiveOrderPoDetailIsActive = 'N', 
                            ReceiveOrderPoDetailDeletedUserID = ?, 
                            ReceiveOrderPoDetailDeleted = NOW() 
                        WHERE ReceiveOrderPoDetailID = ?;
                        ";
        $qry = $this->db->query($sql, [
            $userId,
            $detailID
        ]);
        if (!$qry) {
            $this->sys_error_db("Error update item", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $descDetail = " DELETE ITEM {$detail['M_ItemDesc']} {$detail['tmpQty']} {$detail['ItemUnitName']} {$detail['WarehouseName']}";
        $jsonBefore = $this->getDataPoItemReceive($detail['PoItemReceiveID']);
        $sql = "UPDATE `po_item_receive`
                JOIN receive_order_po_detail
                ON PoItemReceiveID = ReceiveOrderPoDetailPoItemReceiveID
                AND ReceiveOrderPoDetailReceiveOrderPoID = ?
                AND ReceiveOrderPoDetailID = ? 
                    SET 
                        `PoItemReceiveQtyReceived` = PoItemReceiveQtyReceived - ReceiveOrderPoDetailQty, 
                        `PoItemReceiveUpdatedUserID` = ?
                    WHERE `PoItemReceiveID` = ?;";
        $qry = $this->db->query($sql, [
            $ro['ReceiveOrderPoID'],
            $detail['ReceiveOrderPoDetailID'],
            $userId,
            $detail['PoItemReceiveID']
        ]);
        if (!$qry) {
            $this->sys_error_db("Error update item receive", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $jsonAfter = $this->getDataPoItemReceive($detail['PoItemReceiveID']);
        $descItem = "Dihapus {$detail['M_ItemDesc']} sejumlah {$detail['tmpQty']} {$detail['ItemUnitName']} di RO nomor {$jsonROBefore['ReceiveOrderPoNumber']} *RO belum di konfirmasi";
        $this->insertLogPoItemReceive(
            $detail['PoItemReceiveID'],
            'UPDATE',
            $roID,
            $jsonBefore,
            $jsonAfter,
            $userId,
            $descItem
        );
        $jsonROAfter = $this->getDataReceiveOrderPO($roID);
        $this->insertLogReceiveOrderPo(
            $roID,
            'DELETE DETAIL',
            $jsonROBefore,
            $jsonROAfter,
            $userId,
            $descDetail
        );
        $this->insertUserActivty($roID, 'DELETE DETAIL', $userId, $descDetail);
        $this->db->trans_commit();
        $this->sys_ok("Berhasil hapus item {$detail['M_ItemDesc']}");
    }

    public function deleteHeader()
    {
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $this->sys_user["M_UserID"];

        $ro = $prm['ro'];
        $roID = $ro['ReceiveOrderPoID'];
        $jsonROBefore = $this->getDataReceiveOrderPO($roID);
        if ($jsonROBefore['ReceiveOrderPoConfirmed'] === 'Y') {
            $this->sys_error("{$jsonROBefore['ReceiveOrderPoNumber']} tidak bisa di hapus karena sudah di konfirmasi pada {$jsonROBefore['ReceiveOrderPoIDate']}");
            exit;
        }
        $sql = "UPDATE `receive_order_po` SET 
                ReceiveOrderPoIsActive = 'N',
                ReceiveOrderPoDeleted = NOW(),
                `ReceiveOrderPoDeletedUserID` = ?
            WHERE ReceiveOrderPoID = ?;";
        $qry = $this->db->query($sql, [
            $userId,
            $roID
        ]);
        if (!$qry) {
            $this->sys_error_db("Error delete receive oder", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $sql = "SELECT * FROM receive_order_po_detail 
                JOIN m_item 
                ON ReceiveOrderPoItemID = M_ItemID
                JOIN itemunit
                ON ReceiveOrderPoItemUnitID = ItemUnitID
                WHERE ReceiveOrderPoDetailReceiveOrderPoID = ? 
                AND ReceiveOrderPoDetailIsActive = 'Y'";
        $qry = $this->db->query($sql, [
            $roID
        ]);
        if (!$qry) {
            $this->sys_error_db("Error get receive oder detail", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $details = $qry->result_array();
        $descDetail = [];
        foreach ($details as $key => $detail) {
            $detailID = $detail['ReceiveOrderPoDetailID'];
            $sql = "UPDATE receive_order_po_detail 
                        SET 
                            ReceiveOrderPoDetailIsActive = 'N', 
                            ReceiveOrderPoDetailDeletedUserID = ?, 
                            ReceiveOrderPoDetailDeleted = NOW() 
                        WHERE ReceiveOrderPoDetailID = ?;
                        ";
            $qry = $this->db->query($sql, [
                $userId,
                $detailID
            ]);
            if (!$qry) {
                $this->sys_error_db("Error update item", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $descDetail[] = "- DELETE ITEM {$detail['M_ItemDesc']} {$detail['ReceiveOrderPoDetailQty']} {$detail['ItemUnitName']} {$ro['WarehouseName']}";
            $jsonBefore = $this->getDataPoItemReceive($detail['ReceiveOrderPoDetailPoItemReceiveID']);
            $sql = "UPDATE `po_item_receive`
                JOIN receive_order_po_detail
                ON PoItemReceiveID = ReceiveOrderPoDetailPoItemReceiveID
                AND ReceiveOrderPoDetailReceiveOrderPoID = ?
                AND ReceiveOrderPoDetailID = ? 
                    SET 
                        `PoItemReceiveQtyReceived` = PoItemReceiveQtyReceived - ReceiveOrderPoDetailQty, 
                        `PoItemReceiveUpdatedUserID` = ?
                    WHERE `PoItemReceiveID` = ?;";
            $qry = $this->db->query($sql, [
                $ro['ReceiveOrderPoID'],
                $detail['ReceiveOrderPoDetailID'],
                $userId,
                $detail['ReceiveOrderPoDetailPoItemReceiveID']
            ]);
            if (!$qry) {
                $this->sys_error_db("Error update item receive", $this->db);
                $this->db->trans_rollback();
                exit;
            }
            $jsonAfter = $this->getDataPoItemReceive($detail['ReceiveOrderPoDetailPoItemReceiveID']);
            $descItem = "Dihapus {$detail['M_ItemDesc']} sejumlah {$detail['ReceiveOrderPoDetailQty']} {$detail['ItemUnitName']} di RO nomor {$jsonROBefore['ReceiveOrderPoNumber']} *RO belum di konfirmasi";
            $this->insertLogPoItemReceive(
                $detail['ReceiveOrderPoDetailPoItemReceiveID'],
                'UPDATE',
                $roID,
                $jsonBefore,
                $jsonAfter,
                $userId,
                $descItem
            );
        }
        $jsonROAfter = $this->getDataReceiveOrderPO($roID);
        $desc = "Update data Ro {$ro['ReceiveOrderPoNumber']}";

        $this->insertLogReceiveOrderPo(
            $roID,
            'DELETE HEADER',
            $jsonROBefore,
            $jsonROAfter,
            $userId,
            $desc . "\n" . implode("\n", $descDetail)
        );
        $this->insertUserActivty($roID, 'DELETE HEADER', $userId, $desc . "\n" . implode("\n", $descDetail));
        $this->db->trans_commit();
        $this->sys_ok("Berhasil hapus {$ro['ReceiveOrderPoNumber']}");
    }


    public function search()
    {
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $userid = $this->sys_user["M_UserID"];
        $user = $this->sys_user;
        $search = '%' . $prm['search'] . '%';
        $page = $prm["page"];
        $startDate = $prm["startDate"];
        $endDate = $prm["endDate"];

        $ROW_PER_PAGE = 20;
        $start_offset = 0;
        // print_r($prm);

        if (isset($prm["page"])) {
            if (
                is_numeric($prm["page"]) && $prm["page"] > 0
            ) {
                $start_offset = ($page - 1) * $ROW_PER_PAGE;
            }
        }
        $regionalId =  $this->sys_user["S_RegionalID"];
        $sqlWhere = "";

        if ($user['M_UserLocationFlag'] == "R") {
            $sqlWhere = "AND ReceiveOrderPoS_RegionalID ={$regionalId}";
        }
        if ($user['M_UserLocationFlag'] == "RB" || $user['M_UserLocationFlag'] == "B") {
            $sqlWhere = "AND ReceiveOrderPoS_RegionalID = {$regionalId} AND ReceiveOrderPoM_BranchCode LIKE '{$user['M_BranchCode']}%'";
        }

        // Add subquery to filter by ItemCategoryID=4
        $categoryFilter = "AND ReceiveOrderPoID NOT IN (
            SELECT DISTINCT ReceiveOrderPoDetailReceiveOrderPoID 
            FROM receive_order_po_detail 
            JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
            WHERE PurchaseOrderItemCategoryID = 4
            AND ReceiveOrderPoDetailIsActive = 'Y'
        )";

        $sql = "SELECT 
                COUNT(*) as total
                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'
                WHERE ReceiveOrderPoNumber LIKE ?
                AND ReceiveOrderPoIsActive = 'Y'
                AND ReceiveOrderPoIDate BETWEEN ? AND ?
                $sqlWhere
                $categoryFilter";
        $qry = $this->db->query($sql, [$search, $startDate, $endDate]);
        if (!$qry) {
            $this->sys_error_db("Error get total", $this->db);
            exit;
        }
        // print_r($this->db->last_query());
        $total = $qry->row_array()['total'];

        $sql = "SELECT 
                ReceiveOrderPoNumber,
                ReceiveOrderPoID,
                ReceiveOrderPoSupplierID,
                ReceiveOrderPoIDate, 
                ReceiveOrderShippingCostAmount,
                ReceiveOrderPoNote,
                ReceiveOrderPoRefNumber,
                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 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 ReceiveOrderPoNumber LIKE ?
                AND ReceiveOrderPoIsActive = 'Y'
                AND ReceiveOrderPoIDate BETWEEN ? AND ?
                {$sqlWhere}
                {$categoryFilter}
                LIMIT ? OFFSET ?";
        $qry = $this->db->query($sql, [$search, $startDate, $endDate, $ROW_PER_PAGE, $start_offset]);
        if (!$qry) {
            $this->sys_error_db("Error get search", $this->db);
            exit;
        }
        // echo  $this->db->last_query();
        $rst = array(
            "total" => ceil($total / $ROW_PER_PAGE),
            "records" => $qry->result_array()
        );
        $this->sys_ok($rst);
    }
    public function getChecklist()
    {
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $userid = $this->sys_user["M_UserID"];
        $user = $this->sys_user;
        $id = $prm["id"];


        $sql = "SELECT rc.*,
                IFNULL(ReceiveOrderPoChecklistValue, 'N') RoChecklistValue,
                IFNULL(ReceiveOrderPoChecklistNote,'') RoChecklistNote,
                IFNULL (ReceiveOrderPoChecklistID, 0) idCek
                FROM ro_checklist rc
                LEFT JOIN ro_checklist_map rcm ON rc.RoChecklistID = rcm.RoChecklistMapRoChecklistID
                JOIN receive_order_po_detail rop ON rop.ReceiveOrderPoDetailReceiveOrderPoID = ?
                JOIN m_item mi ON mi.M_ItemID = rop.ReceiveOrderPoItemID
                LEFT JOIN receive_order_po_checklist ON rc.RoChecklistID = ReceiveOrderPoChecklistRoChecklistID
                AND ReceiveOrderPoChecklistReceiveOrderPoID = rop.ReceiveOrderPoDetailReceiveOrderPoID
                AND ReceiveOrderPoChecklistIsActive = 'Y'
                WHERE rc.RoChecklistIsActive = 'Y'
                AND (
                    rc.RoChecklistType = 'G'
                    OR (
                        rc.RoChecklistType = 'C'
                        AND rcm.RoChecklistMapItemCategoryID = mi.M_ItemItem_CategoryID
                        AND rcm.RoChecklistMapIsActive = 'Y'
                    )
                    OR (
                        rc.RoChecklistType = 'P'
                        AND rcm.RoChecklistMapNat_GroupID = mi.M_ItemNat_GroupID
                        AND rcm.RoChecklistMapNat_SubGroupID = mi.M_ItemNat_SubGroupID
                        AND rcm.RoChecklistMapIsActive = 'Y'
                    )
                )
                GROUP BY rc.RoChecklistID;";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->sys_error_db("Error get ro checklist", $this->db);
            exit;
        }
        $data = $qry->result_array();
        $cek = 'N';
        foreach ($data as $key => $value) {
            if (intval($value['idCek']) > 0) $cek = 'Y';
        }

        $this->sys_ok([
            "data" => $data,
            "status" => $cek
        ]);
    }
    public function saveChecklist()
    {
        // $this->db->trans_commit();
        // $this->db->trans_rollback();
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $userid = $this->sys_user["M_UserID"];
        $user = $this->sys_user;
        $id = $prm["id"];
        $ron = $prm["ron"];
        $checklist = $prm["checklist"];

        $sql = "SELECT * FROM receive_order_po_checklist WHERE ReceiveOrderPoChecklistReceiveOrderPoID = ? AND ReceiveOrderPoChecklistIsActive = 'Y'";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("get checklist before", $this->db);;
            exit;
        }
        $dataBefore =  $qry->result_array();

        $logMsg = ["Update checklist RO nomor {$ron}"];

        foreach ($checklist as $key => $value) {

            $sql = "SELECT * FROM receive_order_po_checklist 
                    WHERE ReceiveOrderPoChecklistReceiveOrderPoID = ? 
                    AND ReceiveOrderPoChecklistRoChecklistID = ?
                    AND ReceiveOrderPoChecklistIsActive = 'Y'";
            $qry = $this->db->query($sql, [$id, $value['RoChecklistID']]);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("get checklist", $this->db);;
                exit;
            }
            $dataChecklist =  $qry->row_array();
            if (empty($dataChecklist)) {
                //insert 
                $sql = "INSERT INTO receive_order_po_checklist (
                        ReceiveOrderPoChecklistReceiveOrderPoID,
                        ReceiveOrderPoChecklistRoChecklistID,
                        ReceiveOrderPoChecklistValue,
                        ReceiveOrderPoChecklistNote,
                        ReceiveOrderPoChecklistCreated,
                        ReceiveOrderPoChecklistCreatedUserID)
                        VALUES (?, ?, ?, ?, NOW(), ?)";
                $qry = $this->db->query($sql, [
                    $id,
                    $value['RoChecklistID'],
                    $value['RoChecklistValue'],
                    $value['RoChecklistNote'],
                    $userid
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("insert checklist checklist", $this->db);;
                    exit;
                }
                $ket = "memenuhi dan catatan '{$value['RoChecklistNote']}'";
                if ($value['RoChecklistValue'] == 'N') {
                    $ket = "tidak memenuhi dan catatan '{$value['RoChecklistNote']}'";
                }
                $logMsg[] = "- Tambah checklist {$value['RoChecklistName']} dengan nilai {$ket} ";
            } else {
                $sql = "UPDATE receive_order_po_checklist SET
                        ReceiveOrderPoChecklistValue = ?,
                        ReceiveOrderPoChecklistNote = ?,
                        ReceiveOrderPoChecklistLastUpdatedUserID = ?
                        WHERE ReceiveOrderPoChecklistID = ?";
                $qry = $this->db->query($sql, [
                    $value['RoChecklistValue'],
                    $value['RoChecklistNote'],
                    $userid,
                    $dataChecklist['ReceiveOrderPoChecklistID']
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("update checklist checklist", $this->db);;
                    exit;
                }
                $ket = "memenuhi dan catatan '{$value['RoChecklistNote']}'";
                if ($value['RoChecklistValue'] == 'N') {
                    $ket = "tidak memenuhi dan catatan '{$value['RoChecklistNote']}'";
                }
                $logMsg[] = "- Update checklist {$value['RoChecklistName']} dengan nilai {$ket} ";
            }
        }
        $sql = "SELECT * FROM receive_order_po_checklist WHERE ReceiveOrderPoChecklistReceiveOrderPoID = ? AND ReceiveOrderPoChecklistIsActive = 'Y'";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("get checklist before", $this->db);;
            exit;
        }
        $dataAfter =  $qry->result_array();
        $this->insertLogReceiveOrderPo(
            $id,
            'UPDATE CHECKLIST',
            $dataBefore,
            $dataAfter,
            $userid,
            implode("\n", $logMsg)
        );
        $this->insertUserActivty(
            $id,
            'UPDATE CHECKLIST',
            $userid,
            implode("\n", $logMsg)
        );
        $this->db->trans_commit();
        $this->sys_ok("Berhasil simpan checklist");
    }

    private function getCoaTampunganNonPersediaan($itemCategoryID){
        $sqlCoaInventory = "SELECT coaID, coaAccountNo, coaDescription 
            FROM coa_tampungan_nonper
            JOIN coa ON CoaAccountNo_JurnalRO = coaAccountNo
            WHERE CoaTampunganNpM_ItemCategoryID = ?
            AND CoaTampunganNpIsActive = 'Y'
            AND coaIsActive = 'Y';";

        $queCoaInventory = $this->db->query($sqlCoaInventory, [$itemCategoryID]);
        if(!$queCoaInventory){
            $this->db->trans_rollback();
            $this->sys_error("[Error] Gagal mendapatkan CoA Akun Tampungan untuk Item Kategori ID: {$itemCategoryID}");
            exit;
        }
        $coaInventory = $queCoaInventory->row_array();
        return $coaInventory;
    }

    public function confirmRo() {
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        
        $this->db->trans_begin();
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userID = $user['M_UserID'];
        $id = $prm['id'];

        $jsonROBefore = $this->getDataReceiveOrderPO($id);
        $sqlro = "SELECT 
                receive_order_po.*, 
                DATE_FORMAT(ReceiveOrderPoIDate, '%d-%m-%Y') 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 = ?";

        $quero = $this->db->query($sqlro, [$id]);
        if (!$quero) {
            $this->db->trans_rollback();
            $this->sys_error_db("get PO ", $this->db);;
            exit;
        }

        $dataRO = $quero->row_array();
        if ($dataRO['ReceiveOrderPoConfirmed'] == 'Y') {
            $this->db->trans_rollback();
            $this->sys_error("Penerimaan barang {$dataRO['ReceiveOrderPoNumber']} sudah pernah dikonfirmasi");
            exit;
        }

        $sqltotalPO = "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";

        $quetotalPO = $this->db->query($sqltotalPO, [$id]);
        if (!$quetotalPO) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] get detail total qty and price of item po");
            exit;
        }

        $POTotalItem = $quetotalPO->result_array()[0]['totalAllQtyPO'];
        $POTotalPrice = $quetotalPO->result_array()[0]['totalAllPricePO'];

        $sqldetailro = "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";
        $quedetailro = $this->db->query($sqldetailro, [$id]);
        if (!$quedetailro) {
            $this->db->trans_rollback();
            $this->sys_error_db("get ro detail ", $this->db);;
            exit;
        }
        $detailRO = $quedetailro->result_array();
        
        $sqlponum = "SELECT GROUP_CONCAT(DISTINCT PurchaseOrdernumber SEPARATOR ', ') as ponumber
            FROM receive_order_po_detail 
            JOIN purchase_order
            ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
            WHERE ReceiveOrderPoDetailReceiveOrderPoID = ?
            AND ReceiveOrderPoDetailIsActive='Y'";
        $queponum = $this->db->query($sqlponum, [$id]);
        if (!$sqlponum) {
            $this->db->trans_rollback();
            $this->sys_error_db("get ro detail ", $this->db);
            exit; 
        }
        $strPONumber = $queponum->row_array()['ponumber'];
        $desc = "Konfirmasi penerimaan barang {$dataRO['ReceiveOrderPoNumber']} yang meliputi beberapa item dari PO {$strPONumber}";

        // generate jurnal number
        $sqljrnum = "SELECT `fn_numbering`('J') AS numbering";
        $quejrnum = $this->db->query($sqljrnum, []);
        if (!$quejrnum) {
            $this->sys_error_db("get numbering error", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $jurnalNumber = $quejrnum->row_array()["numbering"];

        // get periode jurnal
        $sqlprd = "SELECT periodeID FROM periode
            WHERE DATE(NOW()) BETWEEN periodeStartDate AND periodeEndDate 
            AND periodeIsActive= 'Y' 
            AND periodeIsClosed = 'N'";
        $queprd = $this->db->query($sqlprd, []);
        if (!$queprd) {
            $this->sys_error_db("get periode error", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $jurnalPeriode = $queprd->row_array()['periodeID'];
        if (empty($jurnalPeriode)) {
            $this->sys_error("Periode untuk generate jurnal tidak ditemukan");
            $this->db->trans_rollback();
            exit;
        }

        $jurnalTitle = "Jurnal Penerimaan Barang Dari PO {$strPONumber} Tanggal {$dataRO['formatedDate']}";
        $jurnalDesc = "Jurnal Penerimaan Barang Dari PO {$strPONumber} Tanggal {$dataRO['formatedDate']} Di {$dataRO['WarehouseName']}";
        $descJurnal = "ADD Jurnal Penerimaan Barang Dari PO {$strPONumber} Tanggal {$dataRO['formatedDate']} Di {$dataRO['WarehouseName']}";
        $descJurnalDetail = [];

        $sqljurnaltype = "SELECT JurnalTypeID FROM jurnal_type WHERE JurnalTypeCode = ? AND JurnalTypeIsActive = 'Y'";
        $quejurnaltype = $this->db->query($sqljurnaltype, ['AUTOGOODRECEIVE']);
        if (!$quejurnaltype) {
            $this->sys_error("[Error] jurnal type tidak ditemukan");
            $this->db->trans_rollback();
            exit;
        }
        $jurnalType = $quejurnaltype->row_array()['JurnalTypeID'];

        // insert table jurnal
        $sqlinsjurnal = "INSERT INTO jurnal (
            jurnalM_BranchCompanyID,
            JurnalS_RegionalID,
            jurnalM_BranchCode,
            jurnalperiodeID,
            jurnalNo,
            jurnalTitle,
            jurnalDescription,
            jurnalDate,
            jurnalJurnalTypeID,
            jurnalM_UserID
        ) VALUES (?,?,?,?,?,?,?,NOW(),?,?)";
        $queinsjurnal = $this->db->query($sqlinsjurnal, [
            $user['M_BranchCompanyID'],
            $user['S_RegionalID'],
            $user['M_BranchCode'],
            $jurnalPeriode,
            $jurnalNumber,
            $jurnalTitle,
            $jurnalDesc,
            $jurnalType,
            $userID
        ]);
        if (!$queinsjurnal) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error insert jurnal ", $this->db);;
            exit;
        }
        $jurnalID = $this->db->insert_id();

        // insert jurnal addon
        $sqlinsjurnaladdon = "INSERT INTO jurnal_addon (
            jurnalAddOnJurnalID,
            jurnalAddOnCode,
            jurnalAddOnValue,
            jurnalAddOnCreated,
            jurnalAddOnCreatedUserID
        ) VALUES (?,'RONUMB',?,NOW(),?)";
        $queinsjurnaladdon = $this->db->query($sqlinsjurnaladdon, [
            $jurnalID,
            $dataRO['ReceiveOrderPoNumber'],
            $userID
        ]);
        if (!$queinsjurnaladdon) {
            $this->db->trans_rollback();
            $this->sys_error_db("error insert jurnal addon ", $this->db);;
            exit;
        }

        // update status confirmed RO
        $sqlupdro = "UPDATE `receive_order_po` SET 
                ReceiveOrderPoConfirmed = 'Y',
                ReceiveOrderPoConfirmedDate = NOW(),
                ReceiveOrderPoConfirmedUserID = ?
            WHERE ReceiveOrderPoID = ?";
        $queupdro = $this->db->query($sqlupdro, [$userID, $id]);
        if (!$queupdro) {
            $this->sys_error_db("Error confirm receive oder", $this->db);
            $this->db->trans_rollback();
            exit;
        }

        // insert jurnal tx
        $totalDebet = 0.00;
        $totalDiscountItem = 0.00;
        $totalDiscountPO = 0.00;
        foreach ($detailRO as $key => $item) {
            $sqlitem = "SELECT * FROM m_item WHERE M_ItemID = ?";
            $queitem = $this->db->query($sqlitem, [$item['ReceiveOrderPoItemID']]);
            if (!$queitem) {
                $this->db->trans_rollback();
                $this->sys_error_db("error cek item ", $this->db);;
                exit;
            }
            $cekItem = $queitem->row_array();
            if (empty($cekItem)) {
                $this->db->trans_rollback();
                $this->sys_error_db("Item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} tidak ditemukan ", $this->db);
                exit;
            }
            if (empty($cekItem['M_ItemItem_CategoryID'])) {
                $this->db->trans_rollback();
                $this->sys_error_db("Item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} belum memiliki kategori ", $this->db);
                exit;
            }

            // insert jurnal tx per category
            // ItemCategoryID 1 = Persediaan
            if (intval($cekItem['M_ItemItem_CategoryID']) == 1) {
                if (empty($cekItem['M_ItemNat_SubGroupID'])) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} belum memiliki sub group ", $this->db);
                    exit;
                }
                $sqlnatgroup = "SELECT * FROM map_nat_subgroup
                    WHERE MapNatSub_NatGroupID = ?
                        AND MapNatSub_NatSubGroupID = ?
                        AND MapNatSub_IsActive = 'Y'";
                $quenatgroup = $this->db->query($sqlnatgroup, [
                    $cekItem['M_ItemNat_GroupID'],
                    $cekItem['M_ItemNat_SubGroupID']
                ]);
                if (!$quenatgroup) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error get map_nat_subgroup ", $this->db);;
                    exit;
                }
                $mapNatSubGroup = $quenatgroup->row_array();
                if (empty($mapNatSubGroup['MapNatSub_PersediaanCoaID']) || 
                    empty($mapNatSubGroup['MapNatSub_PersediaanCoaAccountNo']) ||
                    empty($mapNatSubGroup['MapNatSub_PersediaanCoaDescription'])
                ) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Coa item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} belum termapping", $this->db);;
                    exit;
                }

                $debet = round(intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['ReceiveOrderPoDetailPrice']), 2);
                $totalDebet = round($totalDebet + $debet, 2);

                // insert jurnal tx debet
                $sqljtx = "INSERT INTO jurnal_tx (
                        jurnalTxJurnalID,
                        jurnalTxCoaID,
                        jurnalTxDescription,
                        jurnalTxDebit,
                        jurnalTxCredit,
                        jurnalTxM_UserID
                    ) VALUES(?,?,?,?,?,?)";
                $qryjtx = $this->db->query($sqljtx, array(
                    $jurnalID,
                    $mapNatSubGroup['MapNatSub_PersediaanCoaID'],
                    $mapNatSubGroup['MapNatSub_PersediaanCoaDescription'],
                    $debet,
                    0,
                    $userID
                ));
                if (!$qryjtx) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Error insert jurnal tx {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}");
                    exit;
                }
                $jurnalTxID = $this->db->insert_id();
                $formatDebet = $this->formatRupiah($debet);
                $descJurnalDetail[] = "- Add detail Jurnal debet {$cekItem['M_ItemDesc']} {$mapNatSubGroup['MapNatSub_PersediaanCoaDescription']} sejumlah {$formatDebet}";

                $sqladdon = "INSERT INTO jurnal_addon (
                        jurnalAddOnJurnalID,
                        jurnalAddOnJurnalTxID,
                        jurnalAddOnCode,
                        jurnalAddOnValue,
                        jurnalAddOnCreated,
                        jurnalAddOnCreatedUserID
                    ) VALUES (?,?,'PONUMB',?,NOW(),?)";
                $qry = $this->db->query($sqladdon, [
                    $jurnalID,
                    $jurnalTxID,
                    $item['PurchaseOrderNumber'],
                    $userID
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error insert jurnal addon {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}", $this->db);;
                    exit;
                }                

                // insert jurnal tx kredit diskon
                $diskon = round(intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['DiscountPerItem']), 2);
                $totalDiscountItem = round($totalDiscountItem + $diskon, 2);
                // calc discount prorata per item dari discount PO
                $PODiscount = intval($item['DiscPORupiah']);
                if (doubleval($item['DiscPOPercent']) != 0.00) {
                    $PODiscount = doubleval($POTotalPrice) * doubleval($item['DiscPOPercent']) / 100;
                }
                $discProporsiPO = $PODiscount * (doubleval($item['TotalAllPO']) / doubleval($POTotalPrice));
                $discPODiterima = round((intval($item['ReceiveOrderPoDetailQty']) / intval($item['QtyAllPO'])) * $discProporsiPO, 2);
                
                $totalDiscountPO = round($totalDiscountPO + $discPODiterima, 2);
                $listdisc = [$diskon, $discPODiterima];

                $sqlcoa = "SELECT * FROM coa WHERE coaAccountNo = '2190100001' LIMIT 1";
                $quecoa = $this->db->query($sqlcoa, []);
                if (!$quecoa) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get coa diskon pembelian");
                    exit;
                }
                $CoaDisc = $quecoa->result_array()[0];

                foreach ($listdisc as $key => $value) {
                    if (intval($value) != 0) {
                        $quekdt = $this->db->query($sqljtx, [
                            $jurnalID, 
                            $CoaDisc['coaID'], 
                            $CoaDisc['coaDescription'],
                            0, $value, 
                            $userID
                        ]);
                        if (!$quekdt) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert jurnal tx diskon RO: {$item['ReceiveOrderPoDetailID']}");
                            exit;
                        }

                        $jurTxID = $this->db->insert_id();

                        $queaddon = $this->db->query($sqladdon, [ $jurnalID, $jurTxID, $item['PurchaseOrderNumber'], $userID ]);
                        if (!$queaddon) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert jurnal addon diskon");
                            exit;
                        }
                    }
                }

                // save diskon prorata
                $sqldispro = "UPDATE receive_order_po_detail 
                    SET ReceiveOrderPoDetailDiskonPoProrata = ?
                    WHERE ReceiveOrderPoDetailID = ?";
                $quedispro = $this->db->query($sqldispro, [$discPODiterima, $item['ReceiveOrderPoDetailID']]);
                if (!$quedispro) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update detail diskon prorata");
                    exit;
                }
            } else if (intval($cekItem['M_ItemItem_CategoryID']) == 2) {
                // Inventaris (NonPersediaan) selalu memakai CoA akun Tampungan
                // TODO: Update dengan CoA yang Benar
                $coaInventory = $this->getCoaTampunganNonPersediaan(intval($cekItem['M_ItemItem_CategoryID']));

                $debet = round(intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['ReceiveOrderPoDetailPrice']), 2);
                $totalDebet = round($totalDebet + $debet, 2);

                // insert jurnal tx debet
                $sqljtx = "INSERT INTO jurnal_tx (
                        jurnalTxJurnalID,
                        jurnalTxCoaID,
                        jurnalTxDescription,
                        jurnalTxDebit,
                        jurnalTxCredit,
                        jurnalTxM_UserID
                    ) VALUES(?,?,?,?,?,?)";
                $qryjtx = $this->db->query($sqljtx, array(
                    $jurnalID,
                    $coaInventory['coaID'],
                    $coaInventory['coaDescription'],
                    $debet,
                    0,
                    $userID
                ));
                if (!$qryjtx) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Error insert jurnal tx {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}");
                    exit;
                }
                $jurnalTxID = $this->db->insert_id();
                $formatDebet = $this->formatRupiah($debet);
                $descJurnalDetail[] = "- Add detail Jurnal debet {$cekItem['M_ItemDesc']} {$coaInventory['coaDescription']} sejumlah {$formatDebet}";

                $sqladdon = "INSERT INTO jurnal_addon (
                        jurnalAddOnJurnalID,
                        jurnalAddOnJurnalTxID,
                        jurnalAddOnCode,
                        jurnalAddOnValue,
                        jurnalAddOnCreated,
                        jurnalAddOnCreatedUserID
                    ) VALUES (?,?,'PONUMB',?,NOW(),?)";
                $qry = $this->db->query($sqladdon, [
                    $jurnalID,
                    $jurnalTxID,
                    $item['PurchaseOrderNumber'],
                    $userID
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error insert jurnal addon {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}", $this->db);;
                    exit;
                }                

                // insert jurnal tx kredit diskon
                $diskon = round(intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['DiscountPerItem']), 2);
                $totalDiscountItem = round($totalDiscountItem + $diskon, 2);
                // calc discount prorata per item dari discount PO
                $PODiscount = intval($item['DiscPORupiah']);
                if (doubleval($item['DiscPOPercent']) != 0.00) {
                    $PODiscount = doubleval($POTotalPrice) * doubleval($item['DiscPOPercent']) / 100;
                }
                $discProporsiPO = $PODiscount * (doubleval($item['TotalAllPO']) / doubleval($POTotalPrice));
                $discPODiterima = round((intval($item['ReceiveOrderPoDetailQty']) / intval($item['QtyAllPO'])) * $discProporsiPO, 2);
                
                $totalDiscountPO = round($totalDiscountPO + $discPODiterima, 2);
                $listdisc = [$diskon, $discPODiterima];

                $sqlcoa = "SELECT * FROM coa WHERE coaAccountNo = '2190100001' LIMIT 1";
                $quecoa = $this->db->query($sqlcoa, []);
                if (!$quecoa) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get coa diskon pembelian");
                    exit;
                }
                $CoaDisc = $quecoa->result_array()[0];

                foreach ($listdisc as $key => $value) {
                    if (intval($value) != 0) {
                        $quekdt = $this->db->query($sqljtx, [
                            $jurnalID, 
                            $CoaDisc['coaID'], 
                            $CoaDisc['coaDescription'],
                            0, $value, 
                            $userID
                        ]);
                        if (!$quekdt) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert jurnal tx diskon RO: {$item['ReceiveOrderPoDetailID']}");
                            exit;
                        }

                        $jurTxID = $this->db->insert_id();

                        $queaddon = $this->db->query($sqladdon, [ $jurnalID, $jurTxID, $item['PurchaseOrderNumber'], $userID ]);
                        if (!$queaddon) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert jurnal addon diskon");
                            exit;
                        }
                    }
                }

                // save diskon prorata
                $sqldispro = "UPDATE receive_order_po_detail 
                    SET ReceiveOrderPoDetailDiskonPoProrata = ?
                    WHERE ReceiveOrderPoDetailID = ?";
                $quedispro = $this->db->query($sqldispro, [$discPODiterima, $item['ReceiveOrderPoDetailID']]);
                if (!$quedispro) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update detail diskon prorata");
                    exit;
                }

            } else if (intval($cekItem['M_ItemItem_CategoryID']) == 3) {
                //Aset
                if ( empty($cekItem['M_ItemFa_ClassID']) ) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("{$item['PurchaseOrderNumber']} Item {$cekItem['M_ItemDesc']} belum memiliki class asset ", $this->db);
                    exit;
                }

                $sql = "SELECT * FROM fa_class WHERE Fa_ClassID = ? AND Fa_ClassIsActive = 'Y'";
                $qry = $this->db->query($sql, [
                    $cekItem['M_ItemFa_ClassID']
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error get class asset {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} ", $this->db);;
                    exit;
                }
                $faClass = $qry->row_array();
                if (empty($faClass)) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("{$item['PurchaseOrderNumber']} Item {$cekItem['M_ItemDesc']} class asset sudah terhapus", $this->db);;
                    exit;
                }

                $debet = intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['ReceiveOrderPoDetailPrice']);
                $totalDebet = $totalDebet + $debet;
                $sqljtx = "INSERT INTO jurnal_tx (
                        jurnalTxJurnalID,
                        jurnalTxCoaID,
                        jurnalTxDescription,
                        jurnalTxDebit,
                        jurnalTxCredit,
                        jurnalTxM_UserID)
                        VALUES(?,?,?,?,?,?)";
                $qry = $this->db->query($sqljtx, array(
                    $jurnalID,
                    $faClass['Fa_ClassCoaID'],
                    $faClass['Fa_ClassCoaDesc'],
                    $debet,
                    0,
                    $userID
                ));
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Error insert jurnal tx {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}");
                    exit;
                }
                $jurnalTxID = $this->db->insert_id();
                $formatDebet = $this->formatRupiah($debet);
                $descJurnalDetail[] = "- Add detail Jurnal debet {$cekItem['M_ItemDesc']} {$faClass['Fa_ClassCoaDesc']} sejumlah {$formatDebet}";
                
                $sqladdon = "INSERT INTO jurnal_addon (
                        jurnalAddOnJurnalID,
                        jurnalAddOnJurnalTxID,
                        jurnalAddOnCode,
                        jurnalAddOnValue,
                        jurnalAddOnCreated,
                        jurnalAddOnCreatedUserID)
                        VALUES(?,?,'PONUMB',?,NOW(),?)
                        ";
                $qry = $this->db->query($sqladdon, [
                    $jurnalID,
                    $jurnalTxID,
                    $item['PurchaseOrderNumber'],
                    $userID
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error insert jurnal addon {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}", $this->db);
                    exit;
                }

                // insert jurnal tx kredit diskon
                $diskon = intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['DiscountPerItem']);
                $totalDiscountItem = $totalDiscountItem + $diskon;

                // calc discount prorata per item dari discount PO
                $PODiscount = intval($item['DiscPORupiah']);
                if (doubleval($item['DiscPOPercent']) != 0.00) {
                    $PODiscount = doubleval($POTotalPrice) * doubleval($item['DiscPOPercent']) / 100;
                }
                $discProporsiPO = $PODiscount * (doubleval($item['TotalAllPO']) / doubleval($POTotalPrice));
                $discPODiterima = round((intval($item['ReceiveOrderPoDetailQty']) / intval($item['QtyAllPO'])) * $discProporsiPO);
                $totalDiscountPO = $totalDiscountPO + $discPODiterima;
                $listdisc = [$diskon, $discPODiterima];

                $sqlcoa = "SELECT * FROM coa WHERE coaAccountNo = '2190100001' LIMIT 1";
                $quecoa = $this->db->query($sqlcoa, []);
                if (!$quecoa) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get coa diskon pembelian");
                    exit;
                }
                $CoaDisc = $quecoa->result_array()[0];

                foreach ($listdisc as $key => $value) {
                    if (intval($value) != 0) {
                        $quekdt = $this->db->query($sqljtx, [
                            $jurnalID, $CoaDisc['coaID'], $CoaDisc['coaDescription'],
                            0, $value, $userID
                        ]);
                        if (!$quekdt) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert jurnal tx diskon");
                            exit;
                        }
                        $jurTxID = $this->db->insert_id();

                        $queaddon = $this->db->query($sqladdon, [ $jurnalID, $jurTxID, $item['PurchaseOrderNumber'], $userID ]);
                        if (!$queaddon) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert jurnal addon diskon");
                            exit;
                        }
                    }
                }

                // save diskon prorata
                $sqldispro = "UPDATE receive_order_po_detail 
                    SET ReceiveOrderPoDetailDiskonPoProrata = ?
                    WHERE ReceiveOrderPoDetailID = ?";
                $quedispro = $this->db->query($sqldispro, [$discPODiterima, $item['ReceiveOrderPoDetailID']]);
                if (!$quedispro) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update detail diskon prorata");
                    exit;
                }
            } else if(intval($cekItem['M_ItemItem_CategoryID'])== 4){
                // Aset
                // ? Belum tahu apakah Aset masuk ke PR PO RO, tetapi difasilitasi dulu saja seperti inventaris

                // Jasa (NonPersediaan) selalu memakai CoA akun Tampungan
                // TODO: Update dengan CoA yang Benar
                $coaJasa = $this->getCoaTampunganNonPersediaan(intval($cekItem['M_ItemItem_CategoryID']));

                $debet = round(intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['ReceiveOrderPoDetailPrice']), 2);
                $totalDebet = round($totalDebet + $debet, 2);

                // insert jurnal tx debet
                $sqljtx = "INSERT INTO jurnal_tx (
                        jurnalTxJurnalID,
                        jurnalTxCoaID,
                        jurnalTxDescription,
                        jurnalTxDebit,
                        jurnalTxCredit,
                        jurnalTxM_UserID
                    ) VALUES(?,?,?,?,?,?)";
                $qryjtx = $this->db->query($sqljtx, array(
                    $jurnalID,
                    $coaJasa['coaID'],
                    $coaJasa['coaDescription'],
                    $debet,
                    0,
                    $userID
                ));
                if (!$qryjtx) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Error insert jurnal tx {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}");
                    exit;
                }
                $jurnalTxID = $this->db->insert_id();
                $formatDebet = $this->formatRupiah($debet);
                $descJurnalDetail[] = "- Add detail Jurnal debet {$cekItem['M_ItemDesc']} {$coaJasa['coaDescription']} sejumlah {$formatDebet}";

                $sqladdon = "INSERT INTO jurnal_addon (
                        jurnalAddOnJurnalID,
                        jurnalAddOnJurnalTxID,
                        jurnalAddOnCode,
                        jurnalAddOnValue,
                        jurnalAddOnCreated,
                        jurnalAddOnCreatedUserID
                    ) VALUES (?,?,'PONUMB',?,NOW(),?)";
                $qry = $this->db->query($sqladdon, [
                    $jurnalID,
                    $jurnalTxID,
                    $item['PurchaseOrderNumber'],
                    $userID
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error insert jurnal addon {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}", $this->db);;
                    exit;
                }                

                // insert jurnal tx kredit diskon
                $diskon = round(intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['DiscountPerItem']), 2);
                $totalDiscountItem = round($totalDiscountItem + $diskon, 2);
                // calc discount prorata per item dari discount PO
                $PODiscount = intval($item['DiscPORupiah']);
                if (doubleval($item['DiscPOPercent']) != 0.00) {
                    $PODiscount = doubleval($POTotalPrice) * doubleval($item['DiscPOPercent']) / 100;
                }
                $discProporsiPO = $PODiscount * (doubleval($item['TotalAllPO']) / doubleval($POTotalPrice));
                $discPODiterima = round((intval($item['ReceiveOrderPoDetailQty']) / intval($item['QtyAllPO'])) * $discProporsiPO, 2);
                
                $totalDiscountPO = round($totalDiscountPO + $discPODiterima, 2);
                $listdisc = [$diskon, $discPODiterima];

                $sqlcoa = "SELECT * FROM coa WHERE coaAccountNo = '2190100001' LIMIT 1";
                $quecoa = $this->db->query($sqlcoa, []);
                if (!$quecoa) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get coa diskon pembelian");
                    exit;
                }
                $CoaDisc = $quecoa->result_array()[0];

                foreach ($listdisc as $key => $value) {
                    if (intval($value) != 0) {
                        $quekdt = $this->db->query($sqljtx, [
                            $jurnalID, 
                            $CoaDisc['coaID'], 
                            $CoaDisc['coaDescription'],
                            0, $value, 
                            $userID
                        ]);
                        if (!$quekdt) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert jurnal tx diskon RO: {$item['ReceiveOrderPoDetailID']}");
                            exit;
                        }

                        $jurTxID = $this->db->insert_id();

                        $queaddon = $this->db->query($sqladdon, [ $jurnalID, $jurTxID, $item['PurchaseOrderNumber'], $userID ]);
                        if (!$queaddon) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert jurnal addon diskon");
                            exit;
                        }
                    }
                }

                // save diskon prorata
                $sqldispro = "UPDATE receive_order_po_detail 
                    SET ReceiveOrderPoDetailDiskonPoProrata = ?
                    WHERE ReceiveOrderPoDetailID = ?";
                $quedispro = $this->db->query($sqldispro, [$discPODiterima, $item['ReceiveOrderPoDetailID']]);
                if (!$quedispro) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update detail diskon prorata");
                    exit;
                }
            }
            else {
                $this->db->trans_rollback();
                $this->sys_error_db("Item {$cekItem['M_ItemDesc']} kategorinya belum tersedia untuk auto jurnal");
                exit;
            }

            // handle stock

            // check if stock already exist 
            $sqlstockcheck = "SELECT *
                FROM stock
                WHERE StockItemID = ?
                    AND StockItemUnitID = ?
                    AND StockWarehouseID = ?
                    AND StockBatchNo = ?";
            $questockcheck = $this->db->query($sqlstockcheck, [
                $item['ReceiveOrderPoItemID'],
                $item['ReceiveOrderPoItemUnitID'],
                $dataRO['WarehouseID'],
                $item['ReceiveOrderPoDetailBatchNo']
            ]);
            if (!$questockcheck) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] check stock exist or not");
                exit;
            }
            $stockexist = $questockcheck->result_array();

            if (count($stockexist) > 0) {
                $currentStock = intval($stockexist[0]['StockQty']);
                $currentPrice = doubleval($stockexist[0]['StockItemPrice']);

                $newStock = $currentStock + intval($item['ReceiveOrderPoDetailQty']);

                // calculate average price
                $totalAll = ($currentStock * $currentPrice) + (intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['ReceiveOrderPoDetailPrice']));
                $avgPrice = round($totalAll / $newStock, 2);

                $sqlstockupdate = "UPDATE `stock` SET 
                    StockItemPrice = ?,
                    StockQty = ?, 
                    StockLastUpdated = NOW(),
                    StockUserID = ?
                WHERE StockItemID = ?
                    AND StockWarehouseID = ?
                    AND StockBatchNo = ?
                    AND StockItemUnitID = ?";
                $questockupdate = $this->db->query($sqlstockupdate, [
                    $avgPrice,
                    $newStock,
                    $userID,
                    $item['ReceiveOrderPoItemID'],
                    $dataRO['WarehouseID'],
                    $item['ReceiveOrderPoDetailBatchNo'],
                    $item['ReceiveOrderPoItemUnitID']
                ]);
                if (!$questockupdate) {
                    $this->sys_error_db("Error insert update stock");
                    $this->db->trans_rollback();
                    exit;                    
                }
            } else {
                $sql = "INSERT INTO stock (
                    StockWarehouseAlmariID,
                    StockWarehouseRackID,
                    StockWarehouseID,
                    StockStockNumber,
                    StockBatchNo,
                    StockItemID,
                    StockItemUnitID,
                    StockED,
                    StockItemPrice,
                    StockQty,
                    StockLastUpdated,
                    StockUserID
                ) VALUES (0, 0, ?, fn_numbering('SN'), ?, ?, ?, ?, ?, ?, NOW(), ?)
                ON DUPLICATE KEY UPDATE
                    StockItemPrice = VALUES(StockItemPrice),
                    StockQty = StockQty + VALUES(StockQty),
                    StockLastUpdated = NOW(),
                    StockUserID = VALUES(StockUserID);";
                $qry = $this->db->query($sql, array(
                    $dataRO['WarehouseID'],
                    $item['ReceiveOrderPoDetailBatchNo'],
                    $item['ReceiveOrderPoItemID'],
                    $item['ReceiveOrderPoItemUnitID'],
                    $item['ReceiveOrderPoDetailEd'],
                    $item['ReceiveOrderPoDetailPrice'],
                    $item['ReceiveOrderPoDetailQty'],
                    $userID
                ));
                if (!$qry) {
                    $this->sys_error_db("Error insert insert stock");
                    $this->db->trans_rollback();
                    exit;
                }
            }

            $sql = "SELECT * FROM stock 
                WHERE StockWarehouseID = ?
                    AND StockWarehouseAlmariID = 0
                    AND StockWarehouseRackID = 0
                    AND StockBatchNo = ?
                    AND StockItemID = ?
                    AND StockItemUnitID = ?
                    AND StockED = ?";
            $qry = $this->db->query($sql, array(
                $dataRO['WarehouseID'],
                $item['ReceiveOrderPoDetailBatchNo'],
                $item['ReceiveOrderPoItemID'],
                $item['ReceiveOrderPoItemUnitID'],
                $item['ReceiveOrderPoDetailEd'],
            ));
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("Error get stock stock");
                exit;
            }
            $stock = $qry->row_array();

            $sql = "INSERT INTO stockcard (
                    StockCardWarehouseID,
                    StockCardDatetime,
                    StockCardItemID,
                    StockCardItemUnitID,
                    StockCardBatchNo,
                    StockCardED,
                    StockCardReffID,
                    StockCardStatus,
                    StockCardBefore,
                    StockCardIn,
                    StockCardOut,
                    StockCardAfter,
                    StockCardUserID
                ) VALUES (?, NOW(), ?, ?, ?, ?, ?, 'PRV', ?, ?, 0, ?, ?);";
            $qry = $this->db->query($sql, array(
                $dataRO['WarehouseID'],
                $item['ReceiveOrderPoItemID'],
                $item['ReceiveOrderPoItemUnitID'],
                $item['ReceiveOrderPoDetailBatchNo'],
                $item['ReceiveOrderPoDetailEd'],
                $stock['StockID'],
                (intval($stock['StockQty']) - intval($item['ReceiveOrderPoDetailQty'])) < 0 ? 0 : (intval($stock['StockQty']) - intval($item['ReceiveOrderPoDetailQty'])),
                intval($item['ReceiveOrderPoDetailQty']),
                intval($stock['StockQty']),
                $userID
            ));
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("Error insert stock card");
                exit;
            }

            $sql = "INSERT INTO stocklog (
                StockLogWarehouseID,
                StockLogDateTime,
                StockLogItemID,
                StockLogItemUnitID,
                StockLogStockNumber,
                StockLogBatchNo,
                StockLogED,
                StockLogReffID,
                StockLogStatus,
                StockLogQty,
                StockLogUserID
            ) VALUES (?, NOW(), ?, ?, ?, ?, ?, ?, 'PRV', ?, ?);";
            $qry = $this->db->query($sql, array(
                $dataRO['WarehouseID'],
                $item['ReceiveOrderPoItemID'],
                $item['ReceiveOrderPoItemUnitID'],
                $stock['StockStockNumber'],
                $item['ReceiveOrderPoDetailBatchNo'],
                $item['ReceiveOrderPoDetailEd'],
                $stock['StockID'],
                $item['ReceiveOrderPoDetailQty'],
                $userID
            ));
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("Error insert stock log");
                exit;
            }
        }

        // insert jurnal tx for grni
        $totalGRNI = round($totalDebet - ($totalDiscountItem + $totalDiscountPO), 2);
        $sql = "INSERT INTO jurnal_tx (
            jurnalTxJurnalID,
            jurnalTxCoaID,
            jurnalTxDescription,
            jurnalTxDebit,
            jurnalTxCredit,
            jurnalTxM_UserID)
                SELECT 
                    {$jurnalID},
                    coaID,
                    coaDescription,
                    0,
                    {$totalGRNI},
                    {$userID}
                FROM coa WHERE coaAccountNo = '2110100030'
                LIMIT 1";
        $qry = $this->db->query($sql, array());
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error insert jurnal tx GRNI");
            exit;
        }

        $formatDebet = $this->formatRupiah($totalDebet);
        $sql = "INSERT INTO receive_order_po_shipping
                (ReceiveOrderPoShippingPurchaseOrderID,
                ReceiveOrderPoShippingReceiveOrderPoID,
                ReceiveOrderPoShippingAmount,
                ReceiveOrderPoShippingStatus,
                ReceiveOrderPoShippingIsActive,
                ReceiveOrderPoShippingCreatedUserID)
                SELECT 
                PurchaseOrderID,
                {$id},
                PurchaseOrderShippingCost,
                PurchaseOrderShippingCostStatus,
                'Y',
                {$userID}
                FROM purchase_order
                WHERE PurchaseOrderID IN ( SELECT DISTINCT ReceiveOrderPoDetailPurchaseOrderID
                FROM receive_order_po
                JOIN receive_order_po_detail
                ON ReceiveOrderPoDetailReceiveOrderPoID =  ReceiveOrderPoID
                WHERE ReceiveOrderPoID = {$id} )
                AND PurchaseOrderShippingCost IS NOT NULL
                AND PurchaseOrderShippingCost > 0";
        $qry = $this->db->query($sql, array());
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error insert temporary shipping cost");
            exit;
        }

        $descJurnalDetail[] = "- Add detail Jurnal Kredit GRNI sejumlah {$formatDebet}";
        $jsonROAfter = $this->getDataReceiveOrderPO($id);
        $this->insertLogReceiveOrderPo(
            $id,
            'CONFIRM',
            $jsonROBefore,
            $jsonROAfter,
            $userID,
            $desc . "\n" . $descJurnal . "\n" . implode("\n", $descJurnalDetail)
        );
        $this->insertUserActivty(
            $id,
            'CONFIRM',
            $userID,
            $desc . "\n" . $descJurnal . "\n" . implode("\n", $descJurnalDetail)
        );
        $this->db->trans_commit();
        $this->sys_ok("Berhasil konfirmasi terima barang ");
    }


    public function confirmRo_old()
    {
        // $this->db->trans_commit();
        // $this->db->trans_rollback();
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $user = $this->sys_user;
        $userId = $this->sys_user["M_UserID"];
        $id = $prm['id'];

        $jsonROBefore = $this->getDataReceiveOrderPO($id);

        $sql = "SELECT receive_order_po.*, DATE_FORMAT(ReceiveOrderPoIDate, '%d-%m-%Y') 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 = ?";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("get PO ", $this->db);;
            exit;
        }
        $dataRo =  $qry->row_array();

        if ($dataRo['ReceiveOrderPoConfirmed'] == 'Y') {
            $this->db->trans_rollback();
            $this->sys_error("Penerimaan barang {$dataRo['ReceiveOrderPoNumber']} sudah pernah dikonfirmasi");
            exit;
        }

        // jurnal shenanigans
        $tabelNameJurnal = "jurnal";
        $tabelNameJurnaltx = "jurnal_tx";
        $tabelNameJurnalAddon = "jurnal_addon";

        // get total qty and price from the PO
        $sql = "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";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] get detail total qty and price of item po");
            exit;
        }
        $POTotalItem = $qry->result_array()[0]['totalAllQtyPO'];
        $POTotalPrice = $qry->result_array()[0]['totalAllPricePO'];


        $sql = "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";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("get ro detail ", $this->db);;
            exit;
        }
        $detailRo =  $qry->result_array();

        $sql = "SELECT GROUP_CONCAT(DISTINCT PurchaseOrdernumber SEPARATOR ', ') as ponumber
                FROM receive_order_po_detail 
                JOIN purchase_order
                ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
                WHERE ReceiveOrderPoDetailReceiveOrderPoID = ?
                AND ReceiveOrderPoDetailIsActive='Y'";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("get ro detail ", $this->db);;
            exit;
        }
        $strPoNumber =  $qry->row_array()['ponumber'];
        $desc = "Konfirmasi penerimaan barang {$dataRo['ReceiveOrderPoNumber']} yang meliputi beberapa item dari PO {$strPoNumber}";

        // generate numbering jurnal
        $sql = "SELECT `fn_numbering`('J') AS numbering";
        $qry = $this->db->query($sql, []);
        if (!$qry) {
            $this->sys_error_db("get numbering error", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $numbering = $qry->row_array()["numbering"];

        // get peridoe jurnal
        $sql = "SELECT periodeID FROM periode
                WHERE DATE(NOW()) BETWEEN periodeStartDate AND periodeEndDate 
                AND periodeIsActive= 'Y' 
                AND periodeIsClosed = 'N'";
        $qry = $this->db->query($sql, []); //pakai confirm datenya
        if (!$qry) {
            $this->sys_error_db("get periode error", $this->db);
            $this->db->trans_rollback();
            exit;
        }
        $dataPeriode = $qry->row_array();
        if (empty($dataPeriode)) {
            $this->sys_error("Periode untuk generate jurnal tidak ditemukan");
            $this->db->trans_rollback();
            exit;
        }
        $periodeID = $dataPeriode["periodeID"];

        // insert table jurnal
        $jurnalTitle = "Jurnal Penerimaan Barang Dari PO {$strPoNumber} Tanggal {$dataRo['formatedDate']}";
        $jurnalDesc = "Jurnal Penerimaan Barang Dari PO {$strPoNumber} Tanggal {$dataRo['formatedDate']} Di {$dataRo['WarehouseName']}";

        $descJurnal = "ADD Jurnal Penerimaan Barang Dari PO {$strPoNumber} Tanggal {$dataRo['formatedDate']} Di {$dataRo['WarehouseName']}";
        $descJurnalDetail = [];
        $sql = "INSERT INTO {$tabelNameJurnal} (
                jurnalM_BranchCompanyID,
                JurnalS_RegionalID,
                jurnalM_BranchCode,
                jurnalperiodeID,
                jurnalNo,
                jurnalTitle,
                jurnalDescription,
                jurnalDate,
                jurnalJurnalTypeID,
                jurnalM_UserID
            ) VALUES(?,?,?,?,?,?,?,NOW(),?,?)";
        $qry = $this->db->query($sql, [
            $user['M_BranchCompanyID'],
            $user['S_RegionalID'],
            $user['M_BranchCode'],
            $periodeID,
            $numbering,
            $jurnalTitle,
            $jurnalDesc,
            2,
            $userId
        ]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error insert jurnal ", $this->db);;
            exit;
        }
        $jurnalID = $this->db->insert_id();

        // insert jurnal addon
        $sql = "INSERT INTO {$tabelNameJurnalAddon} (
            jurnalAddOnJurnalID,
            jurnalAddOnCode,
            jurnalAddOnValue,
            jurnalAddOnCreated,
            jurnalAddOnCreatedUserID)
            VALUES(?,'RONUMB',?,NOW(),?)
            ";
        $qry = $this->db->query($sql, [
            $jurnalID,
            $dataRo['ReceiveOrderPoNumber'],
            $userId
        ]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("error insert jurnal addon ", $this->db);;
            exit;
        }
        $sql = "UPDATE `receive_order_po` SET 
                ReceiveOrderPoConfirmed = 'Y',
                ReceiveOrderPoConfirmedDate = NOW(),
                ReceiveOrderPoConfirmedUserID = ?
            WHERE ReceiveOrderPoID = ?;";
        $qry = $this->db->query($sql, [
            $userId,
            $id
        ]);
        if (!$qry) {
            $this->sys_error_db("Error confirm receive oder", $this->db);
            $this->db->trans_rollback();
            exit;
        }

        // insert table jurnal tx

        $totalDebet = 0;
        $totalDiscountItem = 0;
        $totalDiscountPO = 0;
        foreach ($detailRo as $key => $item) {
            $sql = "SELECT * FROM m_item WHERE M_ItemID = ?";
            $qry = $this->db->query($sql, [
                $item['ReceiveOrderPoItemID'],
            ]);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("error cek item ", $this->db);;
                exit;
            }
            $cekItem = $qry->row_array();
            if (empty($cekItem)) {
                $this->db->trans_rollback();
                $this->sys_error_db("Item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} tidak ditemukan ", $this->db);
                exit;
            }
            if (empty($cekItem['M_ItemItem_CategoryID'])) {
                $this->db->trans_rollback();
                $this->sys_error_db("Item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} belum memiliki kategori ", $this->db);
                exit;
            }
            
            //persediaan
            if (intval($cekItem['M_ItemItem_CategoryID']) == 1) {
                if (empty($cekItem['M_ItemNat_SubGroupID'])) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} belum memiliki sub group ", $this->db);
                    exit;
                }
                $sql = "SELECT * FROM map_nat_subgroup
                        WHERE MapNatSub_NatGroupID = ?
                        AND MapNatSub_NatSubGroupID = ?
                        AND MapNatSub_IsActive = 'Y'";
                $qry = $this->db->query($sql, [
                    $cekItem['M_ItemNat_GroupID'],
                    $cekItem['M_ItemNat_SubGroupID'],
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error get map_nat_subgroup ", $this->db);;
                    exit;
                }
                $mapNatSubGroup = $qry->row_array();

                if (empty($mapNatSubGroup['MapNatSub_PersediaanCoaID']) || 
                    empty($mapNatSubGroup['MapNatSub_PersediaanCoaAccountNo']) ||
                    empty($mapNatSubGroup['MapNatSub_PersediaanCoaDescription'])
                ) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Coa item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} belum termapping", $this->db);;
                    exit;
                }

                $debet = intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['ReceiveOrderPoDetailPrice']);
                $totalDebet = $totalDebet + $debet;

                // insert jurnal tx debet
                $sqljtx = "INSERT INTO {$tabelNameJurnaltx} (
                        jurnalTxJurnalID,
                        jurnalTxCoaID,
                        jurnalTxDescription,
                        jurnalTxDebit,
                        jurnalTxCredit,
                        jurnalTxM_UserID
                    ) VALUES(?,?,?,?,?,?)";
                $qryjtx = $this->db->query($sqljtx, array(
                    $jurnalID,
                    $mapNatSubGroup['MapNatSub_PersediaanCoaID'],
                    $mapNatSubGroup['MapNatSub_PersediaanCoaDescription'],
                    $debet,
                    0,
                    $userId
                ));
                if (!$qryjtx) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Error insert jurnal tx {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}");
                    exit;
                }

                $jurnalTxID = $this->db->insert_id();
                $formatDebet = $this->formatRupiah($debet);
                $descJurnalDetail[] = "- Add detail Jurnal debet {$cekItem['M_ItemDesc']} {$mapNatSubGroup['MapNatSub_PersediaanCoaDescription']} sejumlah {$formatDebet}";
                $sqladdon = "INSERT INTO {$tabelNameJurnalAddon}(
                        jurnalAddOnJurnalID,
                        jurnalAddOnJurnalTxID,
                        jurnalAddOnCode,
                        jurnalAddOnValue,
                        jurnalAddOnCreated,
                        jurnalAddOnCreatedUserID
                    ) VALUES (?,?,'PONUMB',?,NOW(),?)";
                $qry = $this->db->query($sqladdon, [
                    $jurnalID,
                    $jurnalTxID,
                    $item['PurchaseOrderNumber'],
                    $userId
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error insert jurnal addon {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}", $this->db);;
                    exit;
                }

                // insert jurnal tx kredit diskon
                $diskon = intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['DiscountPerItem']);
                $totalDiscountItem = $totalDiscountItem + $diskon;

                // calc discount prorata per item dari discount PO
                $PODiscount = intval($item['DiscPORupiah']);
                if (doubleval($item['DiscPOPercent']) != 0.00) {
                    $PODiscount = doubleval($POTotalPrice) * doubleval($item['DiscPOPercent']) / 100;
                }
                $discProporsiPO = $PODiscount * (doubleval($item['TotalAllPO']) / doubleval($POTotalPrice));
                $discPODiterima = round((intval($item['ReceiveOrderPoDetailQty']) / intval($item['QtyAllPO'])) * $discProporsiPO);
                $totalDiscountPO = $totalDiscountPO + $discPODiterima;

                $listdisc = [$diskon, $discPODiterima];
                
                $sqlcoa = "SELECT * FROM coa WHERE coaAccountNo = '2190100001' LIMIT 1";
                $quecoa = $this->db->query($sqlcoa, []);
                if (!$quecoa) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get coa diskon pembelian");
                    exit;
                }
                $CoaDisc = $quecoa->result_array()[0];

                foreach ($listdisc as $key => $value) {
                    $quekdt = $this->db->query($sqljtx, [
                        $jurnalID, 
                        $CoaDisc['coaID'], 
                        $CoaDisc['coaDescription'],
                        0, $value, 
                        $userId
                    ]);
                    if (!$quekdt) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] insert jurnal tx diskon RO: {$item['ReceiveOrderPoDetailID']}");
                        exit;
                    }
                    $jurTxID = $this->db->insert_id();

                    $queaddon = $this->db->query($sqladdon, [ $jurnalID, $jurTxID, $item['PurchaseOrderNumber'], $userId ]);
                    if (!$queaddon) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] insert jurnal addon diskon");
                        exit;
                    }
                }

                // save diskon prorata
                $sqldispro = "UPDATE receive_order_po_detail 
                    SET ReceiveOrderPoDetailDiskonPoProrata = ?
                    WHERE ReceiveOrderPoDetailID = ?";
                $quedispro = $this->db->query($sqldispro, [$discPODiterima, $item['ReceiveOrderPoDetailID']]);
                if (!$quedispro) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update detail diskon prorata");
                    exit;
                }

            } else if (intval($cekItem['M_ItemItem_CategoryID']) == 2) {
                //Inventaris
                $this->db->trans_rollback();
                $this->sys_error_db("Item {$cekItem['M_ItemDesc']} memiliki kategori inventaris belum tersedia untuk auto jurnal");
                exit;
            } else if (intval($cekItem['M_ItemItem_CategoryID']) == 3) {
                //Aset
                if ( empty($cekItem['M_ItemFa_ClassID']) ) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("{$item['PurchaseOrderNumber']} Item {$cekItem['M_ItemDesc']} belum memiliki class asset ", $this->db);
                    exit;
                }

                $sql = "SELECT * FROM fa_class WHERE Fa_ClassID = ? AND Fa_ClassIsActive = 'Y'";
                $qry = $this->db->query($sql, [
                    $cekItem['M_ItemFa_ClassID']
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error get class asset {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} ", $this->db);;
                    exit;
                }
                $faClass = $qry->row_array();
                if (empty($faClass)) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("{$item['PurchaseOrderNumber']} Item {$cekItem['M_ItemDesc']} class asset sudah terhapus", $this->db);;
                    exit;
                }
                $debet = intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['ReceiveOrderPoDetailPrice']);
                $totalDebet = $totalDebet + $debet;
                $sqljtx = "INSERT INTO {$tabelNameJurnaltx}(
                        jurnalTxJurnalID,
                        jurnalTxCoaID,
                        jurnalTxDescription,
                        jurnalTxDebit,
                        jurnalTxCredit,
                        jurnalTxM_UserID)
                        VALUES(?,?,?,?,?,?)";
                $qry = $this->db->query($sqljtx, array(
                    $jurnalID,
                    $faClass['Fa_ClassCoaID'],
                    $faClass['Fa_ClassCoaDesc'],
                    $debet,
                    0,
                    $userId
                ));
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Error insert jurnal tx {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}");
                    exit;
                }
                $jurnalTxID = $this->db->insert_id();
                $formatDebet = $this->formatRupiah($debet);
                $descJurnalDetail[] = "- Add detail Jurnal debet {$cekItem['M_ItemDesc']} {$faClass['Fa_ClassCoaDesc']} sejumlah {$formatDebet}";
                $sqladdon = "INSERT INTO {$tabelNameJurnalAddon}(
                        jurnalAddOnJurnalID,
                        jurnalAddOnJurnalTxID,
                        jurnalAddOnCode,
                        jurnalAddOnValue,
                        jurnalAddOnCreated,
                        jurnalAddOnCreatedUserID)
                        VALUES(?,?,'PONUMB',?,NOW(),?)
                        ";
                $qry = $this->db->query($sqladdon, [
                    $jurnalID,
                    $jurnalTxID,
                    $item['PurchaseOrderNumber'],
                    $userId
                ]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("error insert jurnal addon {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']}", $this->db);
                    exit;
                }

                // insert jurnal tx kredit diskon
                $diskon = intval($item['ReceiveOrderPoDetailQty']) * doubleval($item['DiscountPerItem']);
                $totalDiscountItem = $totalDiscountItem + $diskon;

                // calc discount prorata per item dari discount PO
                $PODiscount = intval($item['DiscPORupiah']);
                if (doubleval($item['DiscPOPercent']) != 0.00) {
                    $PODiscount = doubleval($POTotalPrice) * doubleval($item['DiscPOPercent']) / 100;
                }
                $discProporsiPO = $PODiscount * (doubleval($item['TotalAllPO']) / doubleval($POTotalPrice));
                $discPODiterima = round((intval($item['ReceiveOrderPoDetailQty']) / intval($item['QtyAllPO'])) * $discProporsiPO);
                $totalDiscountPO = $totalDiscountPO + $discPODiterima;

                $listdisc = [$diskon, $discPODiterima];

                $sqlcoa = "SELECT * FROM coa WHERE coaAccountNo = '2190100001' LIMIT 1";
                $quecoa = $this->db->query($sqlcoa, []);
                if (!$quecoa) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get coa diskon pembelian");
                    exit;
                }
                $CoaDisc = $quecoa->result_array()[0];

                foreach ($listdisc as $key => $value) {
                    $quekdt = $this->db->query($sqljtx, [
                        $jurnalID, $CoaDisc['coaID'], $CoaDisc['coaDescription'],
                        0, $value, $userId
                    ]);
                    if (!$quekdt) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] insert jurnal tx diskon");
                        exit;
                    }
                    $jurTxID = $this->db->insert_id();

                    $queaddon = $this->db->query($sqladdon, [ $jurnalID, $jurTxID, $item['PurchaseOrderNumber'], $userId ]);
                    if (!$queaddon) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] insert jurnal addon diskon");
                        exit;
                    }
                }

                // save diskon prorata
                $sqldispro = "UPDATE receive_order_po_detail 
                    SET ReceiveOrderPoDetailDiskonPoProrata = ?
                    WHERE ReceiveOrderPoDetailID = ?";
                $quedispro = $this->db->query($sqldispro, [$discPODiterima, $item['ReceiveOrderPoDetailID']]);
                if (!$quedispro) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update detail diskon prorata");
                    exit;
                }
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("Item {$item['PurchaseOrderNumber']} {$cekItem['M_ItemDesc']} belum memiliki kategori ", $this->db);
                exit;
            }
            // handle stock
            $sql = "INSERT INTO stock (
                    StockWarehouseAlmariID,
                    StockWarehouseRackID,
                    StockWarehouseID,
                    StockStockNumber,
                    StockBatchNo,
                    StockItemID,
                    StockItemUnitID,
                    StockED,
                    StockItemPrice,
                    StockQty,
                    StockLastUpdated,
                    StockUserID
                ) VALUES (0, 0, ?, fn_numbering('SN'), ?, ?, ?, ?, ?, ?, NOW(), ?)
                ON DUPLICATE KEY UPDATE
                    StockItemPrice = VALUES(StockItemPrice),
                    StockQty = StockQty + VALUES(StockQty),
                    StockLastUpdated = NOW(),
                    StockUserID = VALUES(StockUserID);";
            $qry = $this->db->query($sql, array(
                $dataRo['WarehouseID'],
                $item['ReceiveOrderPoDetailBatchNo'],
                $item['ReceiveOrderPoItemID'],
                $item['ReceiveOrderPoItemUnitID'],
                $item['ReceiveOrderPoDetailEd'],
                $item['ReceiveOrderPoDetailPrice'],
                $item['ReceiveOrderPoDetailQty'],
                $userId
            ));
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("Error insert update or insert stock");
                exit;
            }

            $sql = "SELECT * FROM stock 
                    WHERE StockWarehouseID = ?
                    AND StockWarehouseAlmariID = 0
                    AND StockWarehouseRackID = 0
                    AND StockBatchNo = ?
                    AND StockItemID = ?
                    AND StockItemUnitID = ?
                    AND StockED = ?
                    ";
            $qry = $this->db->query($sql, array(
                $dataRo['WarehouseID'],
                $item['ReceiveOrderPoDetailBatchNo'],
                $item['ReceiveOrderPoItemID'],
                $item['ReceiveOrderPoItemUnitID'],
                $item['ReceiveOrderPoDetailEd'],
            ));
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("Error get stock stock");
                exit;
            }
            $stock = $qry->row_array();

            $sql = "INSERT INTO stockcard (
                    StockCardWarehouseID,
                    StockCardDatetime,
                    StockCardItemID,
                    StockCardItemUnitID,
                    StockCardBatchNo,
                    StockCardED,
                    StockCardReffID,
                    StockCardStatus,
                    StockCardBefore,
                    StockCardIn,
                    StockCardOut,
                    StockCardAfter,
                    StockCardUserID
                ) VALUES (
                    ?, NOW(), ?, ?, ?, ?, ?, 'PRV', ?, ?, 0, ?, ?
                );";
            $qry = $this->db->query($sql, array(
                $dataRo['WarehouseID'],
                $item['ReceiveOrderPoItemID'],
                $item['ReceiveOrderPoItemUnitID'],
                $item['ReceiveOrderPoDetailBatchNo'],
                $item['ReceiveOrderPoDetailEd'],
                $stock['StockID'],
                (intval($stock['StockQty']) - intval($item['ReceiveOrderPoDetailQty'])) < 0 ? 0 : (intval($stock['StockQty']) - intval($item['ReceiveOrderPoDetailQty'])),
                intval($item['ReceiveOrderPoDetailQty']),
                intval($stock['StockQty']),
                $userId
            ));
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("Error insert stock card");
                exit;
            }

            $sql = "INSERT INTO stocklog (
                        StockLogWarehouseID,
                        StockLogDateTime,
                        StockLogItemID,
                        StockLogItemUnitID,
                        StockLogStockNumber,
                        StockLogBatchNo,
                        StockLogED,
                        StockLogReffID,
                        StockLogStatus,
                        StockLogQty,
                        StockLogUserID
                    ) VALUES (
                        ?, NOW(), ?, ?, ?, ?, ?, ?, 'PRV', ?, ?
                    );";
            $qry = $this->db->query($sql, array(
                $dataRo['WarehouseID'],
                $item['ReceiveOrderPoItemID'],
                $item['ReceiveOrderPoItemUnitID'],
                $stock['StockStockNumber'],
                $item['ReceiveOrderPoDetailBatchNo'],
                $item['ReceiveOrderPoDetailEd'],
                $stock['StockID'],
                $item['ReceiveOrderPoDetailQty'],
                $userId
            ));
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("Error insert stock log");
                exit;
            }
        }

        // insert jurnal tx for grni
        $totalGRNI = $totalDebet - ($totalDiscountItem + $totalDiscountPO);
        $sql = "INSERT INTO {$tabelNameJurnaltx}(
            jurnalTxJurnalID,
            jurnalTxCoaID,
            jurnalTxDescription,
            jurnalTxDebit,
            jurnalTxCredit,
            jurnalTxM_UserID)
                SELECT 
                    {$jurnalID},
                    coaID,
                    coaDescription,
                    0,
                    {$totalGRNI},
                    {$userId}
                FROM coa WHERE coaAccountNo = '2110100030'
                LIMIT 1";
        $qry = $this->db->query($sql, array());
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error insert jurnal tx GRNI");
            exit;
        }


        $formatDebet = $this->formatRupiah($totalDebet);

        $sql = "INSERT INTO receive_order_po_shipping
                (ReceiveOrderPoShippingPurchaseOrderID,
                ReceiveOrderPoShippingReceiveOrderPoID,
                ReceiveOrderPoShippingAmount,
                ReceiveOrderPoShippingStatus,
                ReceiveOrderPoShippingIsActive,
                ReceiveOrderPoShippingCreatedUserID)
                SELECT 
                PurchaseOrderID,
                {$id},
                PurchaseOrderShippingCost,
                PurchaseOrderShippingCostStatus,
                'Y',
                {$userId}
                FROM purchase_order
                WHERE PurchaseOrderID IN ( SELECT DISTINCT ReceiveOrderPoDetailPurchaseOrderID
                FROM receive_order_po
                JOIN receive_order_po_detail
                ON ReceiveOrderPoDetailReceiveOrderPoID =  ReceiveOrderPoID
                WHERE ReceiveOrderPoID = {$id} )
                AND PurchaseOrderShippingCost IS NOT NULL
                AND PurchaseOrderShippingCost > 0
                ";
        $qry = $this->db->query($sql, array());
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error insert temporary shipping cost");
            exit;
        }

        $descJurnalDetail[] = "- Add detail Jurnal Kredit GRNI sejumlah {$formatDebet}";

        $jsonROAfter = $this->getDataReceiveOrderPO($id);


        $this->insertLogReceiveOrderPo(
            $id,
            'CONFIRM',
            $jsonROBefore,
            $jsonROAfter,
            $userId,
            $desc . "\n" . $descJurnal . "\n" . implode("\n", $descJurnalDetail)
        );
        $this->insertUserActivty(
            $id,
            'CONFIRM',
            $userId,
            $desc . "\n" . $descJurnal . "\n" . implode("\n", $descJurnalDetail)
        );
        $this->db->trans_commit();
        $this->sys_ok("Berhasil konfirmasi terima barang ");
    }

    public function generateItemPo()
    {
        $this->db->trans_begin();
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }

        $prm = $this->sys_input;
        $userId = $this->sys_user["M_UserID"];
        $POID = $prm["id"];
        $regionalId = $prm["regionalId"];
        if (!isset($prm['id'])) {
            $this->sys_error("Missing required parameters");
            return;
        }

        $sql = "SELECT * FROM purchase_order 
                LEFT JOIN warehouse ON PurchaseOrderWarehouseID = WarehouseID WHERE PurchaseOrderID = ?";
        $qry = $this->db->query($sql, [$POID]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("get PO ", $this->db);;
            exit;
        }
        $dataPo =  $qry->row_array();
        
        if ($dataPo['PurchaseOrderStatus'] != 'Approved') {
            $this->sys_error("Status Po tidak approved");
            return;
        }
        $dataDetail = [];

        if ($dataPo['PurchaseOrderWarehouseType'] == 'Single') {
            $sql = "SELECT 
                        IFNULL(p.PoItemReceiveID, 0) as receivedID,
                        IFNULL(p.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 p
                        ON pos.PurchaseOrderSummaryPurchaseOrderID = p.PoItemReceivePurchaseOrderID
                    AND  pos.PurchaseOrderSummaryItemID = p.PoItemReceiveItemID 
                    WHERE pos.PurchaseOrderSummaryPurchaseOrderID = ?
                    AND pos.PurchaseOrderSummaryIsActive = 'Y'
                    AND IFNULL(p.PoItemReceiveQtyReceived, 0) = 0
                    ";
            $qry = $this->db->query($sql, [$POID]);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("get item", $this->db);;
                exit;
            }
            $row = $qry->result_array();
            $dataDetail = $row;

            foreach ($row as $key => $v) {
                if (intval($v['PoItemReceiveID']) == 0) {
                    $sql = "INSERT INTO po_item_receive (
                            PoItemReceivePurchaseOrderID,
                            PoItemReceivePurchaseOrderSummaryID,
                            PoItemReceivePurchaseOrderDetailID,
                            PoItemReceiveWarehouseID,
                            PoItemReceiveItemID,
                            PoItemReceiveItemUnitID,
                            PoItemReceiveQty,
                            PoItemReceiveQtyReceived,
                            PoItemReceiveIsActive,
                            PoItemReceiveCreated,
                            PoItemReceiveCreatedUserID,
                            PoItemReceivePrice
                        )
                        VALUES( 
                            ?,
                            ?,
                            ?, 
                            ?,
                            ?,
                            ?,
                            ?,
                            0,  
                            'Y',
                            NOW(),
                            ?,
                            ?
                        )";
                    $qry = $this->db->query($sql, [
                        $POID,
                        $v['orderSummaryID'],
                        $v['PurchaseOrderDetailID'],
                        $dataPo['PurchaseOrderWarehouseID'],
                        $v['itemID'],
                        $v['itemUnitID'],
                        $v['qty'],
                        $userId,
                        $v['price']
                    ]);
                    if (!$qry) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("insert item", $this->db);;
                        exit;
                    }
                    $desc = "ADD {$v['itemName']} {$v['qty']} {$v['itemUnitName']} {$dataPo['WarehouseName']}";
                    $insertedID =  $this->db->insert_id();
                    $jsonAfter = $this->getDataPoItemReceive($insertedID);
                    $this->insertLogPoItemReceive($insertedID, 'ADD', 0, '', $jsonAfter, $userId, $desc);
                }
                if (intval($v['PoItemReceiveID']) != 0) {
                    //boleh update
                    $jsonBefore = $this->getDataPoItemReceive($v['PoItemReceiveID']);
                    $sql = "UPDATE po_item_receive 
                    SET PoItemReceiveQty = ?,
                        PoItemReceiveIsActive = 'Y',
                        PoItemReceiveUpdate = NOW(),
                        PoItemReceiveUpdatedUserID = ?,
                        PoItemReceiveWarehouseID = ?,
                        PoItemReceiveItemUnitID = ?,
                        PoItemReceivePrice = ?
                    WHERE PoItemReceiveID = ?
                    ";
                    $qry = $this->db->query($sql, [
                        $v['qty'],
                        $userId,
                        $dataPo['PurchaseOrderWarehouseID'],
                        $v['itemUnitID'],
                        $v['price'],
                        $v['receivedID']
                    ]);
                    if (!$qry) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("update item ", $this->db);;
                        exit;
                    }
                    $desc = [];
                    if ($jsonBefore['WarehouseID'] != $jsonBefore['WarehouseID']) {
                        $desc[] = "- UPDATE {$v['itemName']} berubah warehouse dari {$jsonBefore['WarehouseName']} menjadi {$jsonAfter['WarehouseName']}";
                    }
                    if ($jsonBefore['PoItemReceiveItemUnitID'] != $jsonBefore['PoItemReceiveItemUnitID']) {
                        $desc[] = "- UPDATE {$v['itemName']} berubah unit item dari {$jsonBefore['ItemUnitName']} menjadi {$jsonAfter['ItemUnitName']}";
                    }
                    if ($jsonBefore['PoItemReceiveQty'] != $jsonBefore['PoItemReceiveQty']) {
                        $desc[] = "- UPDATE {$v['itemName']} berubah jumlah dari {$jsonBefore['PoItemReceiveQty']} menjadi {$jsonAfter['PoItemReceiveQty']}";
                    }
                    if ($jsonBefore['PoItemReceivePrice'] != $jsonBefore['PoItemReceivePrice']) {
                        $desc[] = "- UPDATE {$v['itemName']} berubah harga dari {$jsonBefore['PoItemReceivePrice']} menjadi {$jsonAfter['PoItemReceivePrice']}";
                    }

                    $insertedID =  $this->db->insert_id();
                    $jsonAfter = $this->getDataPoItemReceive($v['PoItemReceiveID']);
                    $this->insertLogPoItemReceive(
                        $v['PoItemReceiveID'],
                        'UPDATE',
                        0,
                        $jsonBefore,
                        $jsonAfter,
                        $userId,
                        implode("\n", $desc)
                    );
                }
            }
        }
        if ($dataPo['PurchaseOrderWarehouseType'] == 'Multiple') {
            $sql = "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'";

            $qry = $this->db->query($sql, [$POID, $POID]);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("get item ", $this->db);;
                exit;
            }
            $mRow = $qry->result_array();
            $dataDetail = $mRow;

            foreach ($mRow as $key => $v) {
                if (intval($v['cekID']) == 0) {
                    $sql = "INSERT INTO po_item_receive (
                                PoItemReceivePurchaseOrderID,
                                PoItemReceivePurchaseOrderSummaryID,
                                PoItemReceivePurchaseOrderDetailID,
                                PoItemReceiveWarehouseID,
                                PoItemReceiveItemID,
                                PoItemReceiveItemUnitID,
                                PoItemReceiveQty,
                                PoItemReceiveQtyReceived,
                                PoItemReceiveIsActive,
                                PoItemReceiveCreated,
                                PoItemReceiveCreatedUserID,
                                PoItemReceivePrice
                            )
                            VALUES( 
                                ?,
                                ?,
                                ?,
                                ?,
                                ?,
                                ?,
                                ?,
                                0,  
                                'Y',
                                NOW(),
                                ?,
                                ?
                            );";
                    $qry = $this->db->query($sql, [
                        $POID,
                        $v['summaryID'],
                        $v['poDetailID'],
                        $v['warehouseID'],
                        $v['itemID'],
                        $v['itemUnitID'],
                        $v['poQty'],
                        $userId,
                        $v['price']
                    ]);
                    if (!$qry) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("insert item", $this->db);;
                        exit;
                    }
                    $desc = "ADD {$v['itemName']} {$v['poQty']} {$v['itemUnitName']} {$v['WarehouseName']}";
                    $insertedID =  $this->db->insert_id();
                    $jsonAfter = $this->getDataPoItemReceive($insertedID);
                    $this->insertLogPoItemReceive($insertedID, 'ADD', 0, '', $jsonAfter, $userId, $desc);
                }
                if (intval($v['cekID']) != 0) {
                    //update
                    $jsonBefore = $this->getDataPoItemReceive($v['cekID']);
                    $sql = "UPDATE po_item_receive p
                            SET 
                                PoItemReceiveQty = ?,
                                PoItemReceiveIsActive = 'Y',
                                PoItemReceiveUpdate = NOW(),
                                PoItemReceiveUpdatedUserID = ?,
                                PoItemReceiveWarehouseID = ?,
                                PoItemReceiveItemUnitID = ?,
                                PoItemReceivePrice = ?
                            WHERE PoItemReceiveID = ?";
                    $qry = $this->db->query($sql, [
                        $v['poQty'],
                        $userId,
                        $v['warehouseID'],
                        $v['itemUnitID'],
                        $v['price'],
                        $v['cekID']
                    ]);
                    if (!$qry) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("update item ", $this->db);;
                        exit;
                    }
                    $desc = [];
                    if ($jsonBefore['WarehouseID'] != $jsonBefore['WarehouseID']) {
                        $desc[] = "- UPDATE {$v['itemName']} berubah warehouse dari {$jsonBefore['WarehouseName']} menjadi {$jsonAfter['WarehouseName']}";
                    }
                    if ($jsonBefore['PoItemReceiveItemUnitID'] != $jsonBefore['PoItemReceiveItemUnitID']) {
                        $desc[] = "- UPDATE {$v['itemName']} berubah unit item dari {$jsonBefore['ItemUnitName']} menjadi {$jsonAfter['ItemUnitName']}";
                    }
                    if ($jsonBefore['PoItemReceiveQty'] != $jsonBefore['PoItemReceiveQty']) {
                        $desc[] = "- UPDATE {$v['itemName']} berubah jumlah dari {$jsonBefore['PoItemReceiveQty']} menjadi {$jsonAfter['PoItemReceiveQty']}";
                    }
                    if ($jsonBefore['PoItemReceivePrice'] != $jsonBefore['PoItemReceivePrice']) {
                        $desc[] = "- UPDATE {$v['itemName']} berubah harga dari {$jsonBefore['PoItemReceivePrice']} menjadi {$jsonAfter['PoItemReceivePrice']}";
                    }

                    $insertedID =  $this->db->insert_id();
                    $jsonAfter = $this->getDataPoItemReceive($v['cekID']);
                    $this->insertLogPoItemReceive(
                        $v['cekID'],
                        'UPDATE',
                        0,
                        $jsonBefore,
                        $jsonAfter,
                        $userId,
                        implode("\n", $desc)
                    );
                }
            }
        }
        $this->db->trans_commit();
        $this->sys_ok([
            'header' => $dataPo,
            'detail' => $dataDetail,
        ]);
    }

    public function getDataReceiveOrderPO($id)
    {
        $sql = "SELECT * FROM 
                receive_order_po
                WHERE ReceiveOrderPoID = ?";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error getDataReceiveOrderPO ", $this->db);;
            exit;
        }
        $header = $qry->row_array();
        $sql = "SELECT * FROM 
                receive_order_po_detail
                WHERE ReceiveOrderPoDetailReceiveOrderPoID = ?
                AND ReceiveOrderPoDetailIsActive";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error getDataReceiveOrderPO detail", $this->db);;
            exit;
        }
        $detail = $qry->row_array();
        $header['details'] = $detail;
        return $header;
    }

    public function getDataPoItemReceive($id)
    {
        $sql = "SELECT * FROM 
                po_item_receive
                JOIN warehouse ON PoItemReceiveWarehouseID= WarehouseID
                JOIN itemunit ON PoItemReceiveItemUnitID = ItemUnitID
                WHERE PoItemReceiveID = ?";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("Error getDataPoItemReceive ", $this->db);;
            exit;
        }
        return $qry->row_array();
    }

    function insertLogReceiveOrderPo($id, $type, $dataBefore, $dataAfter, $userID, $desc = '')
    {
        // Query untuk menyisipkan log ke dalam tabel purchase_order_log
        $sql = "INSERT INTO acc_one_log.receive_order_po_log (
                    ReceiveOrderPoLogReceiveOrderPoID,
                    ReceiveOrderPoLogType,
                    ReceiveOrderPoLogDesc,
                    ReceiveOrderPoLogJsonBefore,
                    ReceiveOrderPoLogJsonAfter,
                    ReceiveOrderPoLogUserID,
                    ReceiveOrderPoLogCreated
                ) VALUES (
                    ?, ?, ?, ?, ?, ?, NOW()
                )";

        // Eksekusi query dengan parameter yang diberikan
        $exec = $this->db->query($sql, [
            $id,
            $type,
            $desc,
            $dataBefore != '' ? json_encode($dataBefore) : '',
            $dataAfter != '' ? json_encode($dataAfter) : "",
            $userID
        ]);

        // Jika query gagal, lempar error
        if (!$exec) {
            $this->sys_error_db("Error inserting log into insert LogReceiveOrderPo", $this->db);
            $this->db->trans_rollback();
            exit;
        }
    }
    function insertLogPoItemReceive($id, $type, $roID, $dataBefore, $dataAfter, $userID, $desc = '')
    {
        // Query untuk menyisipkan log ke dalam tabel purchase_order_log
        $sql = "INSERT INTO acc_one_log.po_item_receive_log (
                    PoItemReceiveLogPoItemReceiveID,
                    PoItemReceiveLogReceiveOrderPoID,
                    PoItemReceiveLogType,
                    PoItemReceiveLogDesc,
                    PoItemReceiveLogJsonBefore,
                    PoItemReceiveLogJsonAfter,
                    PoItemReceiveLogUserID,
                    PoItemReceiveLogCreated
                ) VALUES (
                    ?, ?, ?, ?, ?, ?, ?, NOW()
                )";

        // Eksekusi query dengan parameter yang diberikan
        $exec = $this->db->query($sql, [
            $id,
            $roID,
            $type,
            $desc,
            $dataBefore != '' ? json_encode($dataBefore) : '',
            $dataAfter != '' ? json_encode($dataAfter) : "",
            $userID
        ]);

        // Jika query gagal, lempar error
        if (!$exec) {
            $this->sys_error_db("Error inserting log into po_item_receive_log", $this->db);
            $this->db->trans_rollback();
            exit;
        }
    }
    function insertUserActivty($id, $type, $userID, $desc = '')
    {
        // Query untuk menyisipkan log ke dalam tabel purchase_order_log
        $sql = "INSERT INTO user_activity (
                    UserActivityCode,
                    UserActivityStatus,
                    UserActivityDescription,
                    UserActivityRefID,
                    UserActivityUserID,
                    UserActivityCreated
                ) VALUES (
                    ?, ?, ?, ?, ?, NOW()
                )";

        // Eksekusi query dengan parameter yang diberikan
        $exec = $this->db->query($sql, [
            'RO',
            $type,
            $desc,
            $id,
            $userID

        ]);

        // Jika query gagal, lempar error
        if (!$exec) {
            $this->sys_error_db("Error inserting user activity", $this->db);
            $this->db->trans_rollback();
            exit;
        }
    }
    public function generateItemPoOld()
    {
        if (!$this->isLogin) {
            $this->sys_error("Invalid Token");
            exit;
        }
        $prm = $this->sys_input;
        $userId = $this->sys_user["M_UserID"];
        $POID = $prm["id"];
        $regionalId = $prm["regionalId"];
        if (!isset($prm['id'])) {
            $this->sys_error("Missing required parameters");
            return;
        }

        $sql = "SELECT * FROM purchase_order WHERE PurchaseOrderID = ?";
        $qry = $this->db->query($sql, [$POID]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("get PO ", $this->db);;
            exit;
        }
        $dataPo =  $qry->row_array();
        // print_r($dataPo);
        if ($dataPo['PurchaseOrderStatus'] != 'Approved') {
            $this->sys_error("Status Po tidak approved");
            return;
        }

        if ($dataPo['PurchaseOrderWarehouseType'] == 'Single') {
            $sql = "UPDATE po_item_receive p
                    JOIN purchase_order_summary pos ON p.PoItemReceivePurchaseOrderSummaryID = pos.PurchaseOrderSummaryID
                    SET p.PoItemReceiveQty = pos.PurchaseOrderSummaryQty,
                        p.PoItemReceiveIsActive = 'Y',
                        p.PoItemReceiveUpdate = NOW(),
                        p.PoItemReceiveUpdatedUserID = ?,
                        p.PoItemReceiveWarehouseID = ?,
                        p.PoItemReceiveItemUnitID = pos.PurchaseOrderSummaryItemUnitID,
                        p.PoItemReceivePrice = pos.PurchaseOrderSummaryPrice
                    WHERE p.PoItemReceivePurchaseOrderID = ?
                    AND p.PoItemReceiveItemID = pos.PurchaseOrderSummaryItemID
                    AND p.PoItemReceiveQtyReceived = 0";
            $qry = $this->db->query($sql, [$userId, $dataPo['PurchaseOrderWarehouseID'], $POID]);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("update item ", $this->db);;
                exit;
            }

            $sql = "INSERT INTO po_item_receive (
                PoItemReceivePurchaseOrderID,
                PoItemReceivePurchaseOrderSummaryID,
                PoItemReceivePurchaseOrderDetailID,
                PoItemReceiveWarehouseID,
                PoItemReceiveItemID,
                PoItemReceiveItemUnitID,
                PoItemReceiveQty,
                PoItemReceiveQtyReceived,
                PoItemReceiveIsActive,
                PoItemReceiveCreated,
                PoItemReceiveCreatedUserID,
                PoItemReceivePrice
            )
            SELECT 
                {$POID},
                pos.PurchaseOrderSummaryID,
                NULL, -- Tidak ada detail, karena diambil dari summary
                {$dataPo['PurchaseOrderWarehouseID']},
                pos.PurchaseOrderSummaryItemID,
                pos.PurchaseOrderSummaryItemUnitID,
                pos.PurchaseOrderSummaryQty,
                0,  -- Awalnya belum diterima
                'Y',
                NOW(),
                {$userId},
                pos.PurchaseOrderSummaryPrice
            FROM purchase_order_summary pos
            WHERE pos.PurchaseOrderSummaryPurchaseOrderID = {$POID}
            AND pos.PurchaseOrderSummaryIsActive = 'Y'
            AND NOT EXISTS (
                SELECT 1 FROM po_item_receive p 
                WHERE p.PoItemReceivePurchaseOrderID = {$POID}
                AND p.PoItemReceiveItemID = pos.PurchaseOrderSummaryItemID
            )";
            $qry = $this->db->query($sql, []);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("insert item", $this->db);;
                exit;
            }
        }
        if ($dataPo['PurchaseOrderWarehouseType'] == 'Multiple') {
            $sql = "UPDATE po_item_receive p
                    JOIN purchase_order_detail pod ON p.PoItemReceivePurchaseOrderDetailID = pod.PurchaseOrderDetailID
                    JOIN purchase_order_summary pos ON pod.PurchaseOrderDetailPurchaseSummaryID = pos.PurchaseOrderSummaryID
                    SET 
                        p.PoItemReceiveQty = ConvertQuantityToPurchasedItemUnit(pod.PurchaseOrderDetailItemID, pod.PurchaseOrderDetailItemUnitID, pod.PurchaseOrderDetailQty),
                        p.PoItemReceiveIsActive = 'Y',
                        p.PoItemReceiveUpdate = NOW(),
                        p.PoItemReceiveUpdatedUserID = {$userId},
                        p.PoItemReceiveWarehouseID = pod.PurchaseOrderDetailWarehouseID,
                        p.PoItemReceiveItemUnitID = pos.PurchaseOrderSummaryItemUnitID,
                        p.PoItemReceivePrice = pos.PurchaseOrderSummaryPrice
                    WHERE p.PoItemReceivePurchaseOrderID = {$POID}
                    AND p.PoItemReceivePurchaseOrderSummaryID = pos.PurchaseOrderSummaryID
                    AND p.PoItemReceivePurchaseOrderDetailID = pod.PurchaseOrderDetailID
                    AND p.PoItemReceiveItemID = pod.PurchaseOrderDetailitemID
                    AND p.PoItemReceiveQtyReceived = 0";
            $qry = $this->db->query($sql, []);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("update item ", $this->db);;
                exit;
            }
            $sql = "INSERT INTO po_item_receive (
                PoItemReceivePurchaseOrderID,
                PoItemReceivePurchaseOrderSummaryID,
                PoItemReceivePurchaseOrderDetailID,
                PoItemReceiveWarehouseID,
                PoItemReceiveItemID,
                PoItemReceiveItemUnitID,
                PoItemReceiveQty,
                PoItemReceiveQtyReceived,
                PoItemReceiveIsActive,
                PoItemReceiveCreated,
                PoItemReceiveCreatedUserID,
                PoItemReceivePrice
            )
            SELECT 
                {$POID},
                pod.PurchaseOrderDetailPurchaseSummaryID,
                pod.PurchaseOrderDetailID,
                pod.PurchaseOrderDetailWarehouseID,
                pod.PurchaseOrderDetailItemID,
                pos.PurchaseOrderSummaryItemUnitID,
                ConvertQuantityToPurchasedItemUnit(pod.PurchaseOrderDetailItemID, pod.PurchaseOrderDetailItemUnitID, pod.PurchaseOrderDetailQty),
                0,  -- Awalnya belum diterima
                'Y',
                NOW(),
                {$userId},
                pos.PurchaseOrderSummaryPrice
            FROM purchase_order_detail pod
            JOIN purchase_order_summary pos 
                ON pod.PurchaseOrderDetailPurchaseSummaryID = pos.PurchaseOrderSummaryID
            WHERE pod.PurchaseOrderDetailPurchaseOrderID = {$POID}
            AND pod.PurchaseOrderDetailIsActive = 'Y'
            AND NOT EXISTS (
                SELECT 1 FROM po_item_receive p
                WHERE p.PoItemReceivePurchaseOrderID = {$POID}
                AND p.PoItemReceiveItemID = pod.PurchaseOrderDetailItemID
                AND p.PoItemReceivePurchaseOrderSummaryID = pos.PurchaseOrderSummaryID
                AND p.PoItemReceivePurchaseOrderDetailID = pod.PurchaseOrderDetailID
            );";
            $qry = $this->db->query($sql, []);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("insert item", $this->db);;
                exit;
            }
        }
    }
}
