<?php

class PurchaseOrderAset extends MY_Controller
{
    var $db;
    public function index()
    {
        echo "Purchase Order Aset API";
    }

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

    ## QUERY ##
    public function getListSupplier()
    {
        try {
            if (!$this->isLogin) {
                throw new Exception('Invalid token');
            }

            $sql = "SELECT
                    SupplierID,
                    SupplierName
                FROM supplier
                WHERE SupplierIsActive = 'Y'";
            $que = $this->db->query($sql, []);
            if (!$que) {
                throw new Exception('failed to query list supplier', 1);
            }

            $data = $que->result_array();
            $this->sys_ok($data);
        } catch (Exception $exc) {
            $msg = '[Error] ' . $exc->getMessage();
            $code = $exc->getCode();
            if ($code == 0) {
                $this->sys_error($msg);
            } else {
                $this->sys_error_db($msg);
            }
            exit;
        }
    }

    public function getListCabang()
    {
        try {
            if (!$this->isLogin) {
                throw new Exception('Invalid token');
            }

            $user = $this->sys_user;
            $sql = "SELECT
                M_BranchID,
                M_BranchCode,
                M_BranchName
            FROM m_branch
            WHERE M_BranchIsActive = 'Y'
                AND M_BranchS_RegionalID = ?";
            $que = $this->db->query($sql, [$user['S_RegionalID']]);
            if (!$que) {
                throw new Exception('failed to query list cabang', 1);
            }
            $data = $que->result_array();

            $this->sys_ok($data);
        } catch (Exception $exc) {
            $msg = '[Error] ' . $exc->getMessage();
            $code = $exc->getCode();
            if ($code == 0) {
                $this->sys_error($msg);
            } else {
                $this->sys_error_db($msg);
            }
            exit;
        }
    }

    public function searchRequestAset()
    {
        try {
            if (!$this->isLogin) {
                throw new Exception('Invalid token');
            }

            $para = $this->sys_input;

            $keyword = "%";
            if ($para['search'] != '') {
                $keyword .= $para['search'] . "%";
            }

            $limit = 10;
            $offset = 0;
            if ($para['currpage'] > 0) {
                $offset = ($para['currpage'] - 1) * $limit;
            }

            $sql = "SELECT
                    PurchaseRequestID,
                    PurchaseRequestNumber,
                    PurchaseRequestDetailID,
                    PurchaseRequestFlagID,
                    PurchaseRequestFlagM_BranchCode AS BranchCode,
                    PurchaseRequestItemCategoryID AS ItemCategoryID,
                    PurchaseRequestFlagQtyRest - PurchaseRequestFlagQtyProses AS UnprocessFlagQty,
                    PurchaseRequestDetailQty AS RequestQty,
                    PurchaseRequestDetailQty AS OriginalQty,
                    M_BranchName,
                    M_ItemID,
                    M_ItemCode,
                    M_ItemDesc,
                    ItemUnitID,
                    ItemUnitName,
                    SupplierPricePrice as SupplierPrice
                FROM purchase_request
                JOIN purchase_request_detail ON PurchaseRequestDetailPurchaseRequestID = PurchaseRequestID
                    AND PurchaseRequestDetailIsActive = 'Y'
                    AND PurchaseRequestM_BranchCode = ?
                    AND PurchaseRequestItemCategoryID = '3' -- id category item asset
                    AND PurchaseRequestNumber LIKE ?
                JOIN purchase_request_flag ON PurchaseRequestFlagPurchaseRequestDetailID = PurchaseRequestDetailID
                    AND PurchaseRequestFlagStatus = 'PO'
                    AND PurchaseRequestFlagIsActive = 'Y'
                JOIN m_item ON M_ItemID = PurchaseRequestDetailM_ItemID
                JOIN itemunit ON ItemUnitID = PurchaseRequestDetailItemUnitID
                JOIN supplier_price ON SupplierPriceSupplierID = ?
                    AND SupplierPriceM_ItemID = M_ItemID
                    AND SupplierPriceItemUnitID = ItemUnitID
                    AND SupplierPriceIsActive = 'Y'
                JOIN m_branch ON M_BranchCode = PurchaseRequestFlagM_BranchCode
                    AND M_BranchIsActive = 'Y'
                WHERE NOT EXISTS (
                    SELECT 1
                    FROM purchase_order_detail
                    JOIN purchase_order ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID
                        AND PurchaseOrderStatus = 'Approved'
                        AND PurchaseOrderIsActive = 'Y'
                        AND PurchaseOrderDetailIsActive = 'Y'
                    WHERE PurchaseOrderDetailPurchaseRequestDetailID = PurchaseRequestDetailID
                )";

            $sql_data = $sql . " LIMIT ? OFFSET ? ";
            $que_data = $this->db->query($sql_data, [
                $para['branchcode'],
                $keyword,
                $para['supplierID'],
                $limit,
                $offset
            ]);
            if (!$que_data) {
                throw new Exception('failed to query data request order aset', 1);
            }
            $data = $que_data->result_array();

            $sql_total = "SELECT COUNT(*) AS total FROM ($sql) AS x";
            $que_total = $this->db->query($sql_total, [
                $para['branchcode'],
                $keyword,
                $para['supplierID']
            ]);
            if (!$que_total) {
                throw new Exception('failed to query total request order aset', 1);
            }
            $total = $que_total->row_array()['total'];

            $out = [
                "records" => $data,
                "total" => $total
            ];

            $this->sys_ok($out);
        } catch (Exception $exc) {
            $msg = '[Error] ' . $exc->getMessage();
            $code = $exc->getCode();
            if ($code == 0) {
                $this->sys_error($msg);
            } else {
                $this->sys_error_db($msg);
            }
            exit;
        }
    }

    ## MUTATIONS ##
    public function createPoAsset() {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit;
            }

            $this->db->trans_begin();

            $para = $this->sys_input;
            $user = $this->sys_user;

            /* GENERATE nomor PO */
            $areaid = $user['M_BranchID'];
            $areatype = 'B';
            if ($user['loginLevel'] == 'regional') {
                $areaid = $user['S_RegionalID'];
                $areatype = 'R';
            }

            $sqlusrdivisi = "SELECT M_UserDivisionDivisionID FROM m_userdivision
                WHERE M_UserDivisionM_UserID = ? AND M_UserDivisionIsActive = 'Y'";
            $queusrdivisi = $this->db->query($sqlusrdivisi, [$user['M_UserID']]);
            if (!$queusrdivisi) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get user divisi", $this->db);
                exit;
            }
            $userDivID = $queusrdivisi->row_array()['M_UserDivisionDivisionID'];

            $sqlnum = "SELECT `fn_penomoran`(?, ?, ?, ?, ?, ?) AS numpd;";
            $quenum = $this->db->query($sqlnum, ['PO', $userDivID, $areatype, $areaid, 'SM', 'N']);
            if (!$quenum) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] generate number doc", $this->db);
                exit;
            }
            $numpd = $quenum->row_array()['numpd'];

            /* INSERT into table purchase order */
            $taxtype = 'R';
            $taxpercent = 0;
            if ($para['typepajak'] == 'percent') {
                $taxtype = 'P';
                $taxpercent = floatval($para['valuepajak']);
            }

            $discpercent = 0;
            if ($para['typediskon'] == 'percent') {
                $discpercent = floatval($para['valuediskon']);
            }

            /* summary */
            $summary_subtotal = floatval($para['summary']['subtotal']);
            $summary_diskon = floatval($para['summary']['diskon']);
            $summary_pajak = floatval($para['summary']['pajak']);
            $summary_total = floatval($para['summary']['total']);

            $sql_po = "INSERT INTO purchase_order (
                PurchaseOrderNumber,
                PurchaseOrderItemCategoryID, -- '3' for asset
                PurchaseOrderDate,
                PurchaseOrderRefNumber,
                PurchaseOrderSupplierID,
                PurchaseOrderS_RegionalID,
                PurchaseOrderTaxPpnType,
                PurchaseOrderTaxPercentPpn,
                PurchaseOrderDiscountPercent,
                PurchaseOrderDiscountAmount,
                PurchaseOrderNote,
                PurchaseOrderSubTotal,
                PurchaseOrderTaxAmountPpn,
                PurchaseOrderGrandTotal,
                PurchaseOrderUserID,
                PurchaseOrderCreated
            ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
            $que_po = $this->db->query($sql_po, [
                $numpd, '3', $para['podate'], $para['reference'], $para['supplierID'],
                $user['S_RegionalID'], $taxtype, $taxpercent, $discpercent, $summary_diskon,
                $para['catatan'], $summary_subtotal, $summary_pajak, $summary_total, $user['M_UserID']
            ]);
            if (!$que_po) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] insert into table purchase order");
                exit;
            }
            $PurchaseOrderID = $this->db->insert_id();

            # INSERT into table purchase order summary #
            $summary_detail = $para['detail'];
            $item_detail = [];
            foreach ($summary_detail as $key => $obj) {
                $discpercent = 0;
                $discabsolut = 0;
                if ($obj['DiskonType'] == 'P') {
                    $discpercent = $obj['DiskonAmount'];
                } else {
                    $discabsolut = $obj['DiskonAmount'];
                }

                $sql_summary = "INSERT INTO purchase_order_summary (
                    PurchaseOrderSummaryPurchaseOrderID,
                    PurchaseOrderSummaryItemID,
                    PurchaseOrderSummaryItemUnitID,
                    PurchaseOrderSummaryQty,
                    PurchaseOrderSummaryPrice,
                    PurchaseOrderSummaryTotal,
                    PurchaseOrderSummaryDiscountRupiah,
                    PurchaseOrderSummaryDiscountPercent,
                    PurchaseOrderSummaryDiscountAmount,
                    PurchaseOrderSummaryDiscountType,
                    PurchaseOrderSummaryCreatedUserID,
                    PurchaseOrderSummaryCreated
                ) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW())";
                $que_summary = $this->db->query($sql_summary, [
                    $PurchaseOrderID, $obj['M_ItemID'], $obj['ItemUnitID'],
                    $obj['RequestQty'], $obj['SupplierPrice'], $obj['TempTotal'],
                    $discabsolut, $discpercent, $obj['DiskonAmount'],
                    $obj['DiskonType'], $user['M_UserID']
                ]);
                if (!$que_summary) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] insert into table purchase order summary");
                    exit;
                }

                /* add detail to an array */
                $PurchaseSummaryID = $this->db->insert_id();
                foreach ($obj['detail'] as $key => $value) {
                    $obj['detail'][$key]['PurchaseSummaryID'] = $PurchaseSummaryID;
                    $obj['detail'][$key]['SupplierPrice'] = $obj['SupplierPrice'];
                }

                $item_detail = array_merge($item_detail, $obj['detail']);
            }

            # INSERT into table purchase order detail #
            foreach ($item_detail as $key => $obj) {
                $total = floatval($obj['SupplierPrice']) * floatval($obj['RequestQty']);

                $sql_detail = "INSERT INTO purchase_order_detail (
                    PurchaseOrderDetailPurchaseOrderID,
                    PurchaseOrderDetailPurchaseSummaryID,
                    PurchaseOrderDetailPurchaseRequestID,
                    PurchaseOrderDetailPurchaseRequestDetailID,
                    PurchaseOrderDetailPurchaseRequestFlagID,
                    PurchaseOrderDetailItemID,
                    PurchaseOrderDetailItemUnitID,
                    PurchaseOrderDetailRequestQty,
                    PurchaseOrderDetailQty,
                    PurchaseOrderDetailPrice,
                    PurchaseOrderDetailTotal,
                    PurchaseOrderDetailUserID,
                    PurchaseOrderDetailCreatedUserID,
                    PurchaseOrderDetailCreated
                ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
                $que_detail = $this->db->query($sql_detail, [
                    $PurchaseOrderID, $obj['PurchaseSummaryID'], $obj['PurchaseRequestID'],
                    $obj['PurchaseRequestDetailID'], $obj['PurchaseRequestFlagID'],
                    $obj['M_ItemID'], $obj['ItemUnitID'], $obj['OriginalQty'], $obj['RequestQty'],
                    $obj['SupplierPrice'], $total, $user['M_UserID'], $user['M_UserID']
                ]);
                if (!$que_detail) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] insert into purchase order detail");
                    exit;
                }

                /* purchase request update flag */
                $sql_flag = "UPDATE purchase_request_flag SET
                    PurchaseRequestFlagQtyProses = ?
                WHERE PurchaseRequestFlagID = ?";
                $que_flag = $this->db->query($sql_flag, [
                    $obj['RequestQty'], $obj['PurchaseRequestFlagID']
                ]);
                if (!$que_flag) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update purchase request flag");
                    exit;
                }
            }

            # INSERT into table purchase_order_asset_contract #
            $sql_contract = "INSERT INTO purchase_order_asset_contract (
                PurchaseOrderAssetContractPurchaseOrderID,
                PurchaseOrderAssetContractTAssetAttachmentID,
                PurchaseOrderAssetContractName,
                PurchaseOrderAssetContractDate,
                PurchaseOrderAssetContractStartDate,
                PurchaseOrderAssetContractEndDate,
                PurchaseOrderAssetContractDuration,
                PurchaseOrderAssetContractInstallmentNumber,
                PurchaseOrderAssetContractInstallmentDate,
                PurchaseOrderAssetContractInstallmentPayAmount,
                PurchaseOrderAssetContractInstallmentDownPaymentType,
                PurchaseOrderAssetContractInstallmentDownPayment,
                PurchaseOrderAssetContractCreatedUserID,
                PurchaseOrderAssetContractCreated,
                PurchaseOrderAssetContractLastUpdated,
                PurchaseOrderAssetContractIsActive
            ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW(),'Y')";
            $que_contract = $this->db->query($sql_contract, [
                $PurchaseOrderID,
                $para['assetAttachmentID'],
                $para['contractName'],
                $para['contractDate'],
                $para['contractStart'],
                $para['contractEnd'],
                $para['contractDuration'] ?: 1,
                $para['installmentNumber'] ?: 1,
                $para['installmentDate'] ?: 1,
                $para['installmentPayAmount'] ?: 0.00,
                $para['installmentDownPaymentType'] ?: 'nominal',
                $para['installmentDownPayment'] ?: 0.00,
                $user['M_UserID']
            ]);
            if (!$que_contract) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] insert into table purchase order asset contract");
                exit;
            }

            $this->insertLog(
                $PurchaseOrderID, 'CREATE', $para, '',
                [], $user['M_UserID'], 'create purchase order asset'
            );
            $this->db->trans_commit();
            $this->sys_ok("[Success] success save po asset");
        } catch (Exception $exc) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

    public function editPoAsset() {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit;
            }

            $this->db->trans_begin();

            $para = $this->sys_input;
            $user = $this->sys_user;

            # check tipe diskon dan pajak #
            $taxtype = 'R';
            $taxpercent = 0;
            if ($para['typepajak'] == 'percent') {
                $taxtype = 'P';
                $taxpercent = floatval($para['valuepajak']);
            }

            $discpercent = 0;
            if ($para['typediskon'] == 'percent') {
                $discpercent = floatval($para['valuediskon']);
            }

            # get data summary #
            $summary_subtotal = floatval($para['summary']['subtotal']);
            $summary_diskon = floatval($para['summary']['diskon']);
            $summary_pajak = floatval($para['summary']['pajak']);
            $summary_total = floatval($para['summary']['total']);

            # update po header #
            $sql_po = "UPDATE purchase_order SET 
                PurchaseOrderDate = ?,
                PurchaseOrderRefNumber = ?,
                PurchaseOrderSupplierID = ?,
                PurchaseOrderS_RegionalID = ?,
                PurchaseOrderTaxPpnType = ?,
                PurchaseOrderTaxPercentPpn = ?,
                PurchaseOrderDiscountPercent = ?,
                PurchaseOrderDiscountAmount = ?,
                PurchaseOrderNote = ?,
                PurchaseOrderSubTotal = ?,
                PurchaseOrderTaxAmountPpn = ?,
                PurchaseOrderGrandTotal = ?,
                PurchaseOrderLastUpdated = NOW()
            WHERE PurchaseOrderID = ? 
                AND PurchaseOrderIsActive = 'Y'";
            $que_po = $this->db->query($sql_po, [
                $para['podate'], $para['reference'], $para['supplierID'], $user['S_RegionalID'],
                $taxtype, $taxpercent, $discpercent, $summary_diskon, $para['catatan'],
                $summary_subtotal, $summary_pajak, $summary_total, $para['PurchaseOrderID']
            ]);
            if (!$que_po) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed update header purchase order");
                exit;
            }

            # update purchase_order_asset_contract #
            $sql_contract = "UPDATE purchase_order_asset_contract SET 
                PurchaseOrderAssetContractTAssetAttachmentID = ?,
                PurchaseOrderAssetContractName = ?,
                PurchaseOrderAssetContractDate = ?,
                PurchaseOrderAssetContractStartDate = ?,
                PurchaseOrderAssetContractEndDate = ?,
                PurchaseOrderAssetContractDuration = ?,
                PurchaseOrderAssetContractInstallmentNumber = ?,
                PurchaseOrderAssetContractInstallmentDate = ?,
                PurchaseOrderAssetContractInstallmentPayAmount = ?,
                PurchaseOrderAssetContractInstallmentDownPaymentType = ?,
                PurchaseOrderAssetContractInstallmentDownPayment = ?,
                PurchaseOrderAssetContractLastUpdated = NOW()
            WHERE PurchaseOrderAssetContractID = ? 
                AND PurchaseOrderAssetContractIsActive = 'Y'";
            $que_contract = $this->db->query($sql_contract, [
                $para['assetAttachmentID'],
                $para['contractName'],
                $para['contractDate'],
                $para['contractStart'],
                $para['contractEnd'],
                $para['contractDuration'] ?: 1,
                $para['installmentNumber'] ?: 1,
                $para['installmentDate'] ?: 1,
                $para['installmentPayAmount'] ?: 0.00,
                $para['installmentDownPaymentType'] ?: 'nominal',
                $para['installmentDownPayment'] ?: 0.00,
                $para['PurchaseOrderAssetContractID']
            ]);
            if (!$que_contract) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed update purchase order asset contract");
                exit;
            }

            # update status old po summary isActive to 'N' #
            $sql_active = "UPDATE purchase_order_summary SET 
                PurchaseOrderSummaryIsActive = 'N'
            WHERE PurchaseOrderSummaryPurchaseOrderID = ? 
                AND PurchaseOrderSummaryIsActive = 'Y'";
            $que_active = $this->db->query($sql_active, [$para['PurchaseOrderID']]);
            if (!$que_active) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed update status po summary to N");
                exit;
            }

            # insert new po summary #
            $summary_detail = $para['detail'];
            $item_detail = [];
            foreach ($summary_detail as $key => $obj) {
                $discpercent = 0;
                $discabsolut = 0;
                if ($obj['DiskonType'] == 'P') {
                    $discpercent = $obj['DiskonAmount'];
                } else {
                    $discabsolut = $obj['DiskonAmount'];
                }

                $sql_summary = "INSERT INTO purchase_order_summary (
                    PurchaseOrderSummaryPurchaseOrderID,
                    PurchaseOrderSummaryItemID,
                    PurchaseOrderSummaryItemUnitID,
                    PurchaseOrderSummaryQty,
                    PurchaseOrderSummaryPrice,
                    PurchaseOrderSummaryTotal,
                    PurchaseOrderSummaryDiscountRupiah,
                    PurchaseOrderSummaryDiscountPercent,
                    PurchaseOrderSummaryDiscountAmount,
                    PurchaseOrderSummaryDiscountType,
                    PurchaseOrderSummaryCreatedUserID,
                    PurchaseOrderSummaryCreated
                ) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW())";
                $que_summary = $this->db->query($sql_summary, [
                    $para['PurchaseOrderID'], $obj['M_ItemID'], $obj['ItemUnitID'],
                    $obj['RequestQty'], $obj['SupplierPrice'], $obj['TempTotal'],
                    $discabsolut, $discpercent, $obj['DiskonAmount'],
                    $obj['DiskonType'], $user['M_UserID']
                ]);
                if (!$que_summary) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed update data purchase order summary");
                    exit;
                }

                $PurchaseSummaryID = $this->db->insert_id();
                foreach ($obj['detail'] as $key => $value) {
                    $obj['detail'][$key]['PurchaseSummaryID'] = $PurchaseSummaryID;
                }
                $item_detail = array_merge($item_detail, $obj['detail']);
            }

            # update status po detail isActive to 'N' #
            $sql_active = "UPDATE purchase_order_detail SET 
                PurchaseOrderDetailIsActive = 'N'
            WHERE PurchaseOrderDetailPurchaseOrderID = ?
                AND PurchaseOrderDetailIsActive = 'Y'";
            $que_active = $this->db->query($sql_active, [$para['PurchaseOrderID']]);
            if (!$que_active) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed update status po detail to N");
                exit;
            }

            # insert new po detail #
            foreach ($item_detail as $key => $obj) {
                $total = floatval($obj['SupplierPrice']) * floatval($obj['RequestQty']);

                $sql_detail = "INSERT INTO purchase_order_detail (
                    PurchaseOrderDetailPurchaseOrderID,
                    PurchaseOrderDetailPurchaseSummaryID,
                    PurchaseOrderDetailPurchaseRequestID,
                    PurchaseOrderDetailPurchaseRequestDetailID,
                    PurchaseOrderDetailPurchaseRequestFlagID,
                    PurchaseOrderDetailItemID,
                    PurchaseOrderDetailItemUnitID,
                    PurchaseOrderDetailRequestQty,
                    PurchaseOrderDetailQty,
                    PurchaseOrderDetailPrice,
                    PurchaseOrderDetailTotal,
                    PurchaseOrderDetailUserID,
                    PurchaseOrderDetailCreatedUserID,
                    PurchaseOrderDetailCreated
                ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
                $que_detail = $this->db->query($sql_detail, [
                    $para['PurchaseOrderID'], $obj['PurchaseSummaryID'], $obj['PurchaseRequestID'],
                    $obj['PurchaseRequestDetailID'], $obj['PurchaseRequestFlagID'],
                    $obj['M_ItemID'], $obj['ItemUnitID'], $obj['OriginalQty'], $obj['RequestQty'],
                    $obj['SupplierPrice'], $total, $user['M_UserID'], $user['M_UserID']
                ]);
                if (!$que_detail) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed re-insert purchase order detail");
                    exit;
                }

                $sql_flag = "UPDATE purchase_request_flag SET
                    PurchaseRequestFlagQtyProses = ? 
                WHERE PurchaseRequestFlagID = ?";
                $que_flag = $this->db->query($sql_flag, [
                    $obj['RequestQty'], $obj['PurchaseRequestFlagID']
                ]);
                if (!$que_flag) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed update qty proses flag");
                    exit;
                }
            }

            $this->insertLog(
                $para['PurchaseOrderID'], 'UPDATE', $para, '',
                [], $user['M_UserID'], 'edit purchase order asset'
            );
            $this->db->trans_commit();
            $this->sys_ok("[success] update purchase order asset");
        } catch (Exception $exc) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

    public function deletePoAsset() {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit;
            }

            $this->db->trans_begin();
            $para = $this->sys_input;
            $user = $this->sys_user;

            $sql_detail = "SELECT 
                PurchaseOrderDetailPurchaseRequestFlagID,
                PurchaseOrderDetailQty
            FROM purchase_order_detail 
            WHERE PurchaseOrderDetailPurchaseOrderID = ? 
                AND PurchaseOrderDetailIsActive = 'Y'";
            $que_detail = $this->db->query($sql_detail, [$para['poID']]);
            if (!$que_detail) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed current data purchase order detail asset");
                exit;
            }
            $asset_detail = $que_detail->result_array();

            /* reduce qty process in purchase order flag */
            foreach ($asset_detail as $key => $obj) {
                $sql_updateflag = "UPDATE purchase_request_flag SET
                    PurchaseRequestFlagQtyProses = PurchaseRequestFlagQtyProses - ?
                WHERE PurchaseRequestFlagID = ?";
                $que_updateflag = $this->db->query($sql_updateflag, [
                    $obj['PurchaseOrderDetailQty'],
                    $obj['PurchaseOrderDetailPurchaseRequestFlagID']
                ]);
                if (!$que_updateflag) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed to update qty po asset");
                    exit;
                }
            }

            /* soft delete purchase order detail */
            $sql_deldetail = "UPDATE purchase_order_detail SET 
                PurchaseOrderDetailIsActive = 'N', 
                PurchaseOrderDetailDeleted = NOW(),
                PurchaseOrderDetailDeletedUserID = ? 
            WHERE PurchaseOrderDetailPurchaseOrderID = ?";
            $que_deldetail = $this->db->query($sql_deldetail, [
                $user['M_UserID'], $para['poID']
            ]);
            if (!$que_deldetail) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed soft delete data purchase order detail");
                exit;
            }

            /* soft delete purchase order summary */
            $sql_delsummary = "UPDATE purchase_order_summary SET
                PurchaseOrderSummaryIsActive = 'N',
                PurchaseOrderSummaryDeleted = NOW(),
                PurchaseOrderSummaryDeletedUserID = ? 
            WHERE PurchaseOrderSummaryPurchaseOrderID = ?";
            $que_delsummary = $this->db->query($sql_delsummary, [
                $user['M_UserID'], $para['poID']
            ]);
            if (!$que_delsummary) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed soft delete data purchase order summary");
                exit;
            }

            /* soft delete purchase_order_asset_contract */
            $sql_delcontract = "UPDATE purchase_order_asset_contract SET 
                PurchaseOrderAssetContractIsActive = 'N',
                PurchaseOrderAssetContractLastUpdated = NOW()
            WHERE PurchaseOrderAssetContractID = ? 
                AND PurchaseOrderAssetContractPurchaseOrderID = ?";
            $que_delcontract = $this->db->query($sql_delcontract, [
                $para['contractID'], $para['poID']
            ]);
            if (!$que_delcontract) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed soft delete data purchase order asset contract");
                exit;
            }

            /* soft delete purchase order */
            $sql_delorder = "UPDATE purchase_order SET 
                PurchaseOrderIsActive = 'N',
                PurchaseOrderDeleted = NOW(),
                PurchaseOrderDeletedUserID = ? 
            WHERE PurchaseOrderID = ?";
            $que_delorder = $this->db->query($sql_delorder, [
                $user['M_UserID'], $para['poID']
            ]);
            if (!$que_delorder) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed soft delete data purchase order");
                exit;
            }

            $desc = "delete purchase order asset dengan nomor {$para['ponumber']}";
            $this->insertLog($para['poID'], 'DELETE', $para, '', [], $user['M_UserID'], $desc);

            $this->db->trans_commit();
            $this->sys_ok("[Success] {$desc}");
        } catch (Exception $exc) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

    public function getUserApproveLevel() {
        try {
            if (!$this->isLogin) {
                throw new Exception('Invalid token');
            }

            $user = $this->sys_user;
            $sql = "SELECT M_UserM_ApproveLevelID
                FROM m_user
                WHERE M_UserIsActive = 'Y'
                    AND M_UserID = ? ";
            $que = $this->db->query($sql, [$user['M_UserID']]);
            if (!$que) {
                throw new Exception('failed to query approval level', 1);
            }
            $data = $que->row_array();

            $this->sys_ok($data);
        } catch (Exception $exc) {
            $msg = '[Error] ' . $exc->getMessage();
            $code = $exc->getCode();
            if ($code == 0) {
                $this->sys_error($msg);
            } else {
                $this->sys_error_db($msg);
            }
            exit;
        }
    }

    private function insertLog($poID, $type, $prm, $dataBefore, $dataAfter, $userID, $desc = '') {
        $sql = "INSERT INTO acc_one_log.purchase_order_log (
            PurchaseOrderLogPurchaseOrderID,
            PurchaseOrderLogType,
            PurchaseOrderLogPrm,
            PurchaseOrderLogJSONBefore,
            PurchaseOrderLogJSONAfter,
            PurchaseOrderLogCreated,
            PurchaseOrderLogUserID,
            PurchaseOrderLogTypeDesc
        ) VALUES (?,?,?,?,?,NOW(),?,?)";
        $que = $this->db->query($sql, [
            $poID, $type, json_encode($prm), json_encode($dataBefore),
            json_encode($dataAfter), $userID, $desc
        ]);
        if (!$que) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] failed insert into table log PO");
            exit;
        }
    }
}
