<?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) {
                $this->sys_error("invalid token");
                exit;
            }

            $sql = "SELECT
                SupplierID,
                SupplierName
            FROM supplier
            WHERE SupplierIsActive = 'Y'";
            $que = $this->db->query($sql, []);
            if (!$que) {
                $this->sys_error_db("[Error] get data supplier");
                exit;
            }

            $data = $que->result_array();
            $this->sys_ok($data);
        } catch (Exception $exc) {
            $this->sys_error($exc->getMessage());
        }
    }

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

            $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) {
                $this->sys_error_db("[Error] failed get list cabang");
                exit;
            }

            $data = $que->result_array();
            $this->sys_ok($data);
        } catch (Exception $exc) {
            $this->sys_error($exc->getMessage());
        }
    }

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

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

            $sql = "SELECT
                WarehouseID,
                WarehouseCode,
                WarehouseName
            FROM warehouse
            WHERE WarehouseIsActive = 'Y'
                AND WarehouseS_RegionalID = ?
                AND WarehouseM_BranchID = ?
                AND WarehouseIsTransit = 'N'";
            $que = $this->db->query($sql, [
                $user['S_RegionalID'], $para['M_BranchID']
            ]);
            if (!$que) {
                $this->sys_error_db("[Error] failed get list gudang");
                exit;
            }

            $data = $que->result_array();
            $this->sys_ok($data);
        } catch (Exception $exc) {
            $this->sys_error($exc->getMessage());
        }
    }

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

            $para = $this->sys_input;

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

            $limit = 10;

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

            $sql_data = $sql . " LIMIT ? ";
            $que_data = $this->db->query($sql_data, [
                $keyword, $keyword, $para['branchID'], $para['supplierID'],
                $limit
            ]);
            if (!$que_data) {
                $this->sys_error_db("[Error] get daftar request data");
                exit;
            }
            $data = $que_data->result_array();

            $sql_total = "SELECT COUNT(*) AS total FROM ($sql) AS x";
            $que_total = $this->db->query($sql_total, [
                $keyword, $keyword, $para['branchID'], $para['supplierID']
            ]);
            if (!$que_total) {
                $this->sys_error_db("[Error] get total request aset");
                exit;
            }
            $total = $que_total->row_array()['total'];

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

            $this->sys_ok($out);
        } catch (Exception $exc) {
            $this->sys_error($exc->getMessage());
        }
    }

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

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

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

            $sql_base = "SELECT
                    PurchaseOrderID,
                    PurchaseOrderDate,
                    PurchaseOrderNote,
                    PurchaseOrderNumber,
                    PurchaseOrderStatus,
                    PurchaseOrderRefNumber,
                    PurchaseOrderGrandTotal,
                    PurchaseOrderS_RegionalID,
                    PurchaseOrderApprovedManagerUserID AS verifiedby,
                    IFNULL(PurchaseOrderApprovedUserID, 0) AS approvedby,
                    PurchaseOrderAssetContractID AS contractID,
                    PurchaseOrderAssetContractName AS contractName,
                    PurchaseOrderAssetContractDate AS contractDate,
                    PurchaseOrderAssetContractStartDate AS contractStart,
                    PurchaseOrderAssetContractEndDate AS contractEnd,
                    IFNULL(attach.AttachmentCount, 0) AS AttachmentCount,
                    SupplierID,
                    SupplierName,
                    SupplierDownpaymentID
                FROM purchase_order
                JOIN supplier ON SupplierID = PurchaseOrderSupplierID
                JOIN purchase_order_asset_contract
                    ON PurchaseOrderAssetContractPurchaseOrderID = PurchaseOrderID
                LEFT JOIN supplier_downpayment
                    ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID
                    AND SupplierDownpaymentIsActive = 'Y'
                LEFT JOIN (
                    SELECT
                        ContractAssetAttachmentPurchaseOrderID,
                        ContractAssetAttachmentPurchaseOrderAssetContractID,
                        COUNT(*) AS AttachmentCount
                    FROM contract_asset_attachment
                    WHERE ContractAssetAttachmentIsActive = 'Y'
                    GROUP BY
                        ContractAssetAttachmentPurchaseOrderID,
                        ContractAssetAttachmentPurchaseOrderAssetContractID
                ) attach ON attach.ContractAssetAttachmentPurchaseOrderID = PurchaseOrderID
                    AND attach.ContractAssetAttachmentPurchaseOrderAssetContractID = PurchaseOrderAssetContractID
                WHERE PurchaseOrderIsActive = 'Y'
                    AND PurchaseOrderItemCategoryID = '3'
                    AND PurchaseOrderS_RegionalID = ?
                    AND PurchaseOrderDate BETWEEN DATE(?) AND DATE(?)
                    AND (PurchaseOrderStatus = ? OR 'All' = ?)
                    AND PurchaseOrderNumber LIKE ?";

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

            $sql_data = $sql_base . " LIMIT ? OFFSET ?";
            $que_data = $this->db->query($sql_data, [
                $user['S_RegionalID'], $para['startdate'], $para['enddate'],
                $para['status'], $para['status'], $keyword, $limit, $offset
            ]);
            if (!$que_data) {
                $this->sys_error_db("[Error] failed get data listing PO asset");
                exit;
            }
            $data_services = $que_data->result_array();

            $sql_total = "SELECT COUNT(*) AS total FROM ($sql_base) AS x";
            $que_total = $this->db->query($sql_total, [
                $user['S_RegionalID'], $para['startdate'], $para['enddate'],
                $para['status'], $para['status'], $keyword
            ]);
            if (!$que_total) {
                $this->sys_error_db("[Error] failed get total data listing PO asset");
                exit;
            }
            $total_services = $que_total->row_array()['total'];

            $output = [
                "records" => $data_services,
                "total" => $total_services
            ];

            $this->sys_ok($output);
        } catch (Exception $exc) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

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

            $para = $this->sys_input;

            $sql = "SELECT
                ContractAssetAttachmentID AS attach_id,
                ContractAssetAttachmentFileName AS img_url,
                ContractAssetAttachmentDate AS created
            FROM contract_asset_attachment
            WHERE ContractAssetAttachmentIsActive = 'Y'
                AND ContractAssetAttachmentPurchaseOrderAssetContractID = ?
                AND ContractAssetAttachmentPurchaseOrderID = ?";
            $que = $this->db->query($sql, [
                $para['contractID'], $para['poID']
            ]);
            if (!$que) {
                $this->sys_error_db("[Error] failed get data attachment");
                exit;
            }
            $data = $que->result_array();

            $this->sys_ok($data);
        } catch (Exception $exc) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

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

            $para = $this->sys_input;

            # get data from purchase order detail #
            $sql_detail = "SELECT
                    PurchaseOrderID,
                    PurchaseRequestID,
                    PurchaseRequestNumber,
                    PurchaseOrderDetailPurchaseSummaryID AS PurchaseOrderSummaryID,
                    PurchaseOrderDetailPurchaseRequestDetailID AS PurchaseRequestDetailID,
                    PurchaseOrderDetailPurchaseRequestFlagID AS PurchaseRequestFlagID,
                    PurchaseOrderDetailRequestQty AS OriginalQty,
                    PurchaseOrderDetailQty AS RequestQty,
                    PurchaseOrderDetailPrice AS SupplierPrice,
                    PurchaseOrderDetailTotal,
                    PurchaseOrderDetailItemID AS M_ItemID,
                    M_ItemCode,
                    M_ItemDesc,
                    PurchaseOrderDetailItemUnitID AS ItemUnitID,
                    ItemUnitName
                FROM purchase_order
                JOIN purchase_order_detail ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID
                    AND PurchaseOrderDetailIsActive = 'Y'
                JOIN purchase_request ON PurchaseRequestID = PurchaseOrderDetailPurchaseRequestID
                JOIN m_item ON M_ItemID = PurchaseOrderDetailItemID
                JOIN itemunit ON ItemUnitID = PurchaseOrderDetailItemUnitID
                WHERE PurchaseOrderDetailIsActive = 'Y'
                    AND PurchaseOrderID = ?";
            $que_detail = $this->db->query($sql_detail, [$para['poID']]);
            if (!$que_detail) {
                $this->sys_error_db("[Error] failed get data po detail asset");
                exit;
            }
            $detail_asset = $que_detail->result_array();

            # get data from purchase order summary #
            $sql_sumry = "SELECT
                    PurchaseOrderID,
                    PurchaseOrderSummaryID,
                    PurchaseOrderSummaryQty AS RequestQty,
                    PurchaseOrderSummaryPrice AS SupplierPrice,
                    PurchaseOrderSummaryDiscountRupiah AS DiskonRupiah,
                    PurchaseOrderSummaryDiscountPercent AS DiskonPercent,
                    PurchaseOrderSummaryDiscountAmount AS DiskonAmount,
                    PurchaseOrderSummaryDiscountType AS DiskonType,
                    (PurchaseOrderSummaryPrice - PurchaseOrderSummaryDiscountAmount) AS EndPrice,
                    PurchaseOrderSummaryTotal AS TempTotal,
                    PurchaseOrderSummaryItemID AS M_ItemID,
                    M_ItemCode,
                    M_ItemDesc,
                    PurchaseOrderSummaryItemUnitID AS ItemUnitID,
                    ItemUnitName
                FROM purchase_order
                JOIN purchase_order_summary ON PurchaseOrderSummaryPurchaseOrderID = PurchaseOrderID
                JOIN m_item ON M_ItemID = PurchaseOrderSummaryItemID
                JOIN itemunit ON ItemUnitID = PurchaseOrderSummaryItemUnitID
                WHERE PurchaseOrderSummaryIsActive = 'Y'
                    AND PurchaseOrderID = ?";
            $que_sumry = $this->db->query($sql_sumry, [$para['poID']]);
            if (!$que_sumry) {
                $this->sys_error_db("[Error] failed get data po summary asset");
                exit;
            }
            $data_sumry = $que_sumry->result_array();

            # get data from purchase order #
            $sql_poasset = "SELECT
                    PurchaseOrderID,
                    PurchaseOrderDate AS podate,
                    PurchaseOrderNote AS catatan,
                    PurchaseOrderNumber,
                    PurchaseOrderStatus,
                    PurchaseOrderRefNumber AS reference,
                    PurchaseOrderGrandTotal AS grandtotal,
                    CASE
                        WHEN PurchaseOrderTaxPpnType = 'P' THEN 'percent'
                        ELSE 'nominal'
                    END AS typepajak,
                    CASE
                        WHEN PurchaseOrderTaxPpnType = 'P' THEN PurchaseOrderTaxPercentPpn
                        ELSE PurchaseOrderTaxAmountPpn
                    END AS valuepajak,
                    CASE
                        WHEN PurchaseOrderDiscountPercent > 0.00 THEN 'percent'
                        ELSE 'nominal'
                    END AS typediskon,
                    CASE
                        WHEN PurchaseOrderDiscountPercent > 0.00 THEN PurchaseOrderDiscountPercent
                        ELSE PurchaseOrderDiscountAmount
                    END AS valuediskon,
                    PurchaseOrderSubTotal AS subtotal,
                    PurchaseOrderGrandTotal AS grandtotal,
                    SupplierID AS supplierID,
                    SupplierName,
                    WarehouseID AS gudangID,
                    WarehouseM_BranchID AS branchID,
                    PurchaseOrderAssetContractID,
                    PurchaseOrderAssetContractTAssetAttachmentID AS assetAttachmentID,
                    PurchaseOrderAssetContractName AS contractName,
                    PurchaseOrderAssetContractDate AS contractDate,
                    PurchaseOrderAssetContractStartDate AS contractStart,
                    PurchaseOrderAssetContractEndDate AS contractEnd,
                    PurchaseOrderAssetContractDuration AS contractDuration,
                    PurchaseOrderAssetContractInstallmentNumber AS installmentNumber,
                    PurchaseOrderAssetContractInstallmentDate AS installmentDate,
                    PurchaseOrderAssetContractInstallmentPayAmount AS installmentPayAmount,
                    PurchaseOrderAssetContractInstallmentDownPaymentType AS installmentDownPaymentType,
                    PurchaseOrderAssetContractInstallmentDownPayment AS installmentDownPayment,
                    PurchaseOrderApprovedManagerUserID AS verifiedby,
                    SupplierDownpaymentID
                FROM purchase_order
                JOIN supplier ON SupplierID = PurchaseOrderSupplierID
                JOIN warehouse ON WarehouseID = PurchaseOrderWarehouseID
                JOIN purchase_order_asset_contract
                    ON PurchaseOrderAssetContractPurchaseOrderID = PurchaseOrderID
                LEFT JOIN supplier_downpayment
                    ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID
                    AND SupplierDownpaymentIsActive = 'Y'
                WHERE PurchaseOrderIsActive = 'Y'
                    AND PurchaseOrderID = ?";
            $que_poasset = $this->db->query($sql_poasset, [$para['poID']]);
            if (!$que_poasset) {
                $this->sys_error_db("[Error] failed get data from purchase order");
                exit;
            }
            $datapo = $que_poasset->row_array();

            # process data output #
            /* map detail po to summary */
            $grouped_detailpo = array();
            foreach ($detail_asset as $obj) {
                $idz = $obj['PurchaseOrderSummaryID'];
                if (!isset($grouped_detailpo[$idz])) {
                    $grouped_detailpo[$idz] = array();
                }

                $grouped_detailpo[$idz][] = $obj;
            }

            foreach ($data_sumry as $key => $summary) {
                $ids = $summary['PurchaseOrderSummaryID'];

                if (isset($grouped_detailpo[$ids])) {
                    $data_sumry[$key]['detail'] = $grouped_detailpo[$ids];
                } else {
                    $data_sumry[$key]['detail'] = array();
                }
            }

            $subtotal = floatval($datapo['subtotal']);
            $downpayment = floatval($datapo['installmentDownPayment']);
            $grandtotal = floatval($datapo['grandtotal']);

            $valuediskon = floatval($datapo['valuediskon']);
            if ($datapo['typediskon'] == 'percent') {
                $valuediskon = round(floatval($datapo['valuediskon']) * $subtotal / 100, 2);
            }

            $valuepajak = floatval($datapo['valuepajak']);
            if ($datapo['typepajak'] == 'percent') {
                $price = ($subtotal - $valuediskon);
                $valuepajak = round(floatval($datapo['valuepajak']) *  $price / 100, 2);
            }

            $outsummary = [
                "subtotal" => $subtotal,
                "diskon" => $valuediskon,
                "pajak" => $valuepajak,
                "downpayment" => $downpayment,
                "total_before_downpayment" => $downpayment + $grandtotal,
                "total" => $grandtotal
            ];

            /* map summary to purchase order */
            $datapo['valuepajak'] = floatval($datapo['valuepajak']);
            $datapo['valuediskon'] = floatval($datapo['valuediskon']);
            $datapo['detail'] = $data_sumry;
            $datapo['summary'] = $outsummary;

            $this->sys_ok($datapo);
        } catch (Exception $exc) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

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

            $user = $this->sys_user;
            $sql = "SELECT M_UserM_ApproveLevelID FROM m_user
            WHERE M_UserIsActive = 'Y' AND M_UserID = ? ";
            $que = $this->db->query($sql, [$user['M_UserID']]);
            if (!$que) {
                $this->sys_error_db("[Error] failed get approval level user");
                exit;
            }
            $data = $que->row_array();
            $this->sys_ok($data);
        } catch (Exception $exc) {
            $this->sys_error($exc->getMessage());
        }
    }

    ## MUTATIONS ##
    public function createPoAsset() {
        try {
            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_downpayment = floatval($para['summary']['downpayment']);
            $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,
                    PurchaseOrderWarehouseType,
                    PurchaseOrderWarehouseID,
                    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,
                'single', $para['gudangID'], $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,
                        PurchaseOrderDetailWarehouseID,
                        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, $para['gudangID'], $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;
            }

            # INSERT into table supplier_downpayment #
            $sql_dp = "INSERT INTO supplier_downpayment (
                    SupplierDownpaymentPurchasOrderID,
                    SupplierDownpaymentSupplierID,
                    SupplierDownpaymentAmount,
                    SupplierDownpaymentDate,
                    SupplierDownpaymentDueDate,
                    SupplierDownpaymentStatus,
                    SupplierDownpaymentCreatedUserID,
                    SupplierDownpaymentLastUpdatedUserID
                ) VALUES (?,?,?,?,?,?,?,?)";
            $que_dp = $this->db->query($sql_dp, [
                $PurchaseOrderID,
                $para['supplierID'],
                $summary_downpayment ?: 0.00,
                $para['contractStart'],
                $para['contractStart'],
                'Draft',
                $user['M_UserID'],
                $user['M_UserID']
            ]);
            if (!$que_dp) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed insert supplier downpayment");
                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_downpayment = floatval($para['summary']['downpayment']);
            $summary_total = floatval($para['summary']['total']);

            # update po header #
            $sql_po = "UPDATE purchase_order SET
                PurchaseOrderDate = ?,
                PurchaseOrderRefNumber = ?,
                PurchaseOrderSupplierID = ?,
                PurchaseOrderS_RegionalID = ?,
                PurchaseOrderTaxPpnType = ?,
                PurchaseOrderTaxPercentPpn = ?,
                PurchaseOrderDiscountPercent = ?,
                PurchaseOrderDiscountAmount = ?,
                PurchaseOrderWarehouseType = ?,
                PurchaseOrderWarehouseID = ?,
                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, 'single', $para['gudangID'],
                $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 existing downpayment ##
            $sql = "UPDATE supplier_downpayment SET
                    SupplierDownpaymentAmount = ?,
                    SupplierDownpaymentDate = ?,
                    SupplierDownpaymentDueDate = ?,
                    SupplierDownpaymentStatus = ?,
                    SupplierDownpaymentLastUpdatedUserID = ?
                WHERE SupplierDownpaymentID = ?
                    AND SupplierDownpaymentIsActive = 'Y'";
            $que = $this->db->query($sql, [
                $summary_downpayment ?: 0.00,
                $para['contractStart'],
                $para['contractStart'],
                'Draft',
                $user['M_UserID'],
                $para['SupplierDownpaymentID']
            ]);
            if (!$que) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed update supplier downpayment");
                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,
                        PurchaseOrderDetailWarehouseID,
                        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, $para['gudangID'], $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;
            }

            $sql_delattac = "UPDATE contract_asset_attachment SET
                    ContractAssetAttachmentIsActive = 'N'
                WHERE ContractAssetAttachmentPurchaseOrderAssetContractID = ?
                    AND ContractAssetAttachmentPurchaseOrderID = ?";
            $que_delattac = $this->db->query($sql_delattac, [
                $para['contractID'], $para['poID']
            ]);
            if (!$que_delattac) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed soft delete data attachment");
                exit;
            }

            /* soft delete supplier_downpayment */
            $sql_deldp = "UPDATE supplier_downpayment SET
                    SupplierDownpaymentIsActive = 'N',
                    SupplierDownpaymentLastUpdatedUserID = ?
                WHERE SupplierDownpaymentID = ?
                    AND SupplierDownpaymentIsActive = 'Y'";
            $que_deldp = $this->db->query($sql_deldp, [
                $user['M_UserID'], $para['SupplierDownpaymentID']
            ]);
            if (!$que_deldp) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed soft delete supplier downpayment");
                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 uploadAttachment() {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit;
            }

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

            $basepath = "/home/one/project/accone/one-media/order-asset/";
            $year = date("Y");
            $targetpath = $basepath . $year . "/";

            if (!is_dir($targetpath)) {
                mkdir($targetpath, 0755, true);
            }

            $config['upload_path'] = $targetpath;
            $config['allowed_types'] = 'jpg|jpeg|png';
            $config['max_size'] = '10000';
            $count = count($_FILES['files']['name']);
            $this->load->library('upload', $config);

            for ($i=0; $i < $count; $i++) {
                if (!empty($_FILES['files']['name'][$i])) {
                    $_FILES['file']['name']     = $_FILES['files']['name'][$i];
                    $_FILES['file']['type']     = $_FILES['files']['type'][$i];
                    $_FILES['file']['tmp_name'] = $_FILES['files']['tmp_name'][$i];
                    $_FILES['file']['error']    = $_FILES['files']['error'][$i];
                    $_FILES['file']['size']     = $_FILES['files']['size'][$i];

                    $ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
                    $new_filename = "PO" . date("YmdHis") . "_" . $para['ponumber'] . "." . $ext;
                    $config['file_name'] = $new_filename;
                    $this->upload->initialize($config);

                    if ($this->upload->do_upload('file')) {
                        $upload_data = $this->upload->data();
                        $filename = $upload_data['file_name'];

                        $sql_insert = "INSERT INTO contract_asset_attachment (
                            ContractAssetAttachmentPurchaseOrderAssetContractID,
                            ContractAssetAttachmentPurchaseOrderID,
                            ContractAssetAttachmentFileName,
                            ContractAssetAttachmentDate,
                            ContractAssetAttachmentCreated
                        ) VALUES (?,?,?,?,NOW())";
                        $que_insert = $this->db->query($sql_insert, [
                            $para['contractID'], $para['poID'],
                            $filename, $para['contractDate']
                        ]);
                        if (!$que_insert) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] failed insert attachment table contract asset attachment");
                            exit;
                        }
                        $attachmentID = $this->db->insert_id();

                        $sql_contract = "UPDATE purchase_order_asset_contract SET
                                PurchaseOrderAssetContractTAssetAttachmentID = ?
                            WHERE PurchaseOrderAssetContractID = ?
                                AND PurchaseOrderAssetContractPurchaseOrderID = ?";
                        $que_contract = $this->db->query($sql_contract, [
                            $attachmentID, $para['contractID'], $para['poID']
                        ]);
                        if (!$que_contract) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] failed update attachmentid into asset contract table");
                            exit;
                        }
                    } else {
                        $error = $this->upload->display_errors();
                        $this->db->trans_rollback();
                        $this->sys_error("[Error] " . $error);
                    }
                }
            }

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

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

            $this->db->trans_begin();
            $para = $this->sys_input;
            $user = $this->sys_user;
            $approvelevel = $para['approvelevel'];

            /* request purchase order */
            if ($approvelevel == '0') {
                $sql = "UPDATE purchase_order SET
                    PurchaseOrderStatus = 'Pending',
                    PurchaseOrderLastUpdated = NOW()
                WHERE PurchaseOrderID = ?
                    AND PurchaseOrderIsActive = 'Y'";
                $que = $this->db->query($sql, [$para['poID']]);
                if (!$que) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed update table purchase order request");
                    exit;
                }
            }

            /* verifikasi oleh manager */
            if ($approvelevel == '1') {
                $sql = "UPDATE purchase_order SET
                    PurchaseOrderApprovedManagerUserID = ?,
                    PurchaseOrderLastUpdated = NOW()
                WHERE PurchaseOrderID = ?
                    AND PurchaseOrderIsActive = 'Y'";
                $que = $this->db->query($sql, [$user['M_UserID'], $para['poID']]);
                if (!$que) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed update table purchase order verif");
                    exit;
                }
            }

            /* approval oleh kepala regional */
            if ($approvelevel == '2') {
                $sql = "UPDATE purchase_order SET
                    PurchaseOrderStatus = 'Approved',
                    PurchaseOrderLastUpdated = NOW(),
                    PurchaseOrderApprovedUserID = ?
                WHERE PurchaseOrderID = ?
                    AND PurchaseOrderIsActive = 'Y'";
                $que = $this->db->query($sql, [$user['M_UserID'], $para['poID']]);
                if (!$que) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed update table purchase order approve");
                    exit;
                }
            }

            $this->db->trans_commit();
            $this->sys_ok("[Success] success update status PO Asset");
        } catch (Exception $exc) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

    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;
        }
    }
}
