<?php

class PurchaseOrderService extends MY_Controller {
    var $db;
    public function index() {
        echo "Purchase Order Jasa";
    }

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

    ## QUERY ##
    public function getDaftarSupplier() {
        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) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

    public function getDaftarCabang() {
        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] get data cabang");
                exit;
            }
            $data = $que->result_array();

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

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

            $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 = '4' -- id category item jasa
                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) {
                $this->sys_error_db("[Error] get daftar request jasa");
                exit;
            }
            $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) {
                $this->sys_error_db("[Error] get total request jasa");
                exit;
            }

            $out = [
                "records" => $data,
                "total" => $que_total->row_array()['total']
            ];

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

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

            $userid = $this->sys_user['M_UserID'];
            $sql_level = "SELECT M_UserM_ApproveLevelID FROM m_user 
            WHERE M_UserIsActive = 'Y' AND M_UserID = ? ";
            $que_level = $this->db->query($sql_level, [$userid]);
            if (!$que_level) {
                $this->sys_error_db("[Error] failed get approval level user");
                exit;
            }
            $data = $que_level->row_array();

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

    public function getDaftarPOJasa() {
        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,
                T_KontrakJasaID,
                SupplierID,
                SupplierName,
                M_BranchID,
                M_BranchName,
                M_BranchCode
            FROM purchase_order 
            JOIN supplier ON SupplierID = PurchaseOrderSupplierID
            JOIN t_kontrak_jasa ON T_KontrakJasaPurchaseOrderID = PurchaseOrderID
            JOIN m_branch ON M_BranchCode = T_KontrakJasaM_BranchCode 
            WHERE PurchaseOrderIsActive = 'Y'
                AND PurchaseOrderItemCategoryID = '4'
                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 jasa");
                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 jasa");
                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 getDataKontrakPOJasa() {
        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,
                T_KontrakJasaM_BranchCode AS BranchCode,
                M_BranchName,
                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 t_kontrak_jasa ON T_KontrakJasaPurchaseOrderID = PurchaseOrderID
            JOIN purchase_request ON PurchaseRequestID = PurchaseOrderDetailPurchaseRequestID
            JOIN m_branch ON M_BranchCode = T_KontrakJasaM_BranchCode
            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 jasa");
                exit;
            }
            $detailjasa = $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 jasa");
                exit;
            }
            $data_sumry = $que_sumry->result_array();

            # get data from purchase order #
            $sql_pojasa = "SELECT
                PurchaseOrderID,
                PurchaseOrderDate AS podate,
                PurchaseOrderNote AS catatan,
                PurchaseOrderNumber,
                PurchaseOrderStatus,
                PurchaseOrderRefNumber AS reference,
                PurchaseOrderGrandTotal AS grandtotal,
                CASE 
                    WHEN PurchaseOrderTaxPpnType = 'P' THEN 'percent'
                    ELSE 'absolute'
                END AS typepajak,
                CASE 
                    WHEN PurchaseOrderTaxPpnType = 'P' THEN PurchaseOrderTaxPercentPpn
                    ELSE PurchaseOrderTaxAmountPpn
                END AS valuepajak,
                CASE
                    WHEN PurchaseOrderDiscountPercent > 0.00 THEN 'percent'
                    ELSE 'absolute'
                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,
                M_BranchID,
                M_BranchName,
                M_BranchCode AS branchcode,
                T_KontrakJasaID,
                T_KontrakJasaJenisKontrak AS typekontrak,
                T_KontrakJasaStartDate AS kontrakstart,
                T_KontrakJasaEndDate AS kontrakend,
                T_KontrakJasaJumlahPI AS PIOutQty,
                PurchaseOrderApprovedManagerUserID AS verifiedby
            FROM purchase_order 
            JOIN supplier ON SupplierID = PurchaseOrderSupplierID
            JOIN t_kontrak_jasa ON T_KontrakJasaPurchaseOrderID = PurchaseOrderID
            JOIN m_branch ON M_BranchCode = T_KontrakJasaM_BranchCode 
            WHERE PurchaseOrderIsActive = 'Y'
                AND PurchaseOrderID = ?";
            $que_pojasa = $this->db->query($sql_pojasa, [$para['poID']]);
            if (!$que_pojasa) {
                $this->sys_error_db("[Error] failed get data from purchase order");
                exit;
            }
            $datapo = $que_pojasa->row_array();

            # process data output #
            /* map detail po to summary */ 
            $grouped_detailpo = array();
            foreach ($detailjasa 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']);
            $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,
                "total" => $grandtotal
            ];
            /* map summary to purchase order */ 
            $datapo['valuepajak'] = floatval($datapo['valuepajak']);
            $datapo['valuediskon'] = floatval($datapo['valuediskon']);
            $datapo['detail'] = $data_sumry;
            $datapo['summary'] = $outsummary;

            /* for debugging */ 
            // $output = [
            //     "po" => $datapo,
            //     "summary" => $data_sumry,
            //     "detail" => $detailjasa,
            //     "grouped" => $grouped_detailpo
            // ];
            // $this->sys_ok($output);


            $this->sys_ok($datapo);
        } 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 
                T_JasaAttachmentID AS attach_id, 
                T_JasaAttachmentName AS img_url,
                T_JasaAttachmentCreated AS created
            FROM t_jasa_attachment
            WHERE T_JasaAttachmentIsActive = 'Y'
                AND T_JasaAttachmentT_KontrakJasaID = ?
                AND T_JasaAttachmentPurchaseOrderID = ?
                AND T_JasaAttachmentType = 'order'";
            $que = $this->db->query($sql, [
                $para['TJasaID'], $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);
        }
    }

    ## MUTATIONS ##
    public function createPOjasa() {
        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, -- '4' 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, '4', $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 intp 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 t_kontrak_jasa #
            $sql_contract = "INSERT INTO t_kontrak_jasa (
                T_KontrakJasaPurchaseOrderID,
                T_KontrakJasaM_BranchCode,
                T_KontrakJasaJenisKontrak,
                T_KontrakJasaStartDate,
                T_KontrakJasaEndDate,
                T_KontrakJasaJumlahPI
            ) VALUES(?,?,?,?,?,?)";
            $que_contract = $this->db->query($sql_contract, [
                $PurchaseOrderID, $para['branchcode'], $para['typekontrak'], 
                $para['kontrakstart'], $para['kontrakend'], $para['PIOutQty']
            ]);
            if (!$que_contract) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] insert into table kontrak jasa");
                exit;
            }

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

    public function editPOjasa() {
        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 service 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 t kontrak jasa #
            $sql_kontrak = "UPDATE t_kontrak_jasa SET 
                T_KontrakJasaM_BranchCode = ?,
                T_KontrakJasaJenisKontrak = ?,
                T_KontrakJasaStartDate = ?,
                T_KontrakJasaEndDate = ?,
                T_KontrakJasaJumlahPI = ?
            WHERE T_KontrakJasaID = ? 
                AND T_KontrakJasaIsActive = 'Y'";
            $que_kontrak = $this->db->query($sql_kontrak, [
                $para['branchcode'], $para['typekontrak'], $para['kontrakstart'], 
                $para['kontrakend'], $para['PIOutQty'], $para['T_KontrakJasaID']
            ]);
            if (!$que_kontrak) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed update t kontrak jasa");
                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;
            }

            # update 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 tp '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;
            }

            # update 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 purchae order jasa'
            );
            $this->db->trans_commit();
            $this->sys_ok("[success] update purchase order jasa");
        } catch (Exception $exc) {
            $msg = $exc->getMessage();
            $this->sys_error($msg);
        }
    }

    public function deletePOjasa() {
        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 jasa");
                exit;
            }
            $jasa_detail = $que_detail->result_array();

            /* reduce qty process in purchase order flag */ 
            foreach ($jasa_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 jasa");
                    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 t kontrak jasa */ 
            $sql_deljasa = "UPDATE t_kontrak_jasa SET 
                T_KontrakJasaIsActive = 'N',
                T_KontrakJasaDeleted = NOW()
            WHERE T_KontrakJasaID = ? 
                AND T_KontrakJasaPurchaseOrderID = ?";
            $que_deljasa = $this->db->query($sql_deljasa, [
                $para['tjasaID'], $para['poID']
            ]);
            if (!$que_deljasa) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] failed soft delete data t kontrak jasa");
                exit;
            }

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

            $desc = "delete purchase order jasa 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-jasa/";
            $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 t_jasa_attachment (
                            T_JasaAttachmentT_KontrakJasaID,
                            T_JasaAttachmentPurchaseOrderID,
                            T_JasaAttachmentName,
                            T_JasaAttachmentType,
                            T_JasaAttachmentCreated
                        ) VALUES (?,?,?,?,NOW())";
                        $que_insert = $this->db->query($sql_insert, [
                            $para['tjasaID'], $para['poID'], $filename, 'order'
                        ]);
                        if (!$que_insert) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] failed insert attachment table t jasa attachment");
                            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 jasa");
        } 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;
                }

                $sql_cont = "UPDATE t_kontrak_jasa SET 
                    T_KontrakJasaStatus = 'active',
                    T_KontrakJasaLastUpdated = NOW()
                WHERE T_KontrakJasaID = ?";
                $que_cont = $this->db->query($sql_cont, [$para['kontrakid']]);
                if (!$que_cont) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed update table t kontrak jasa");
                    exit;
                }
            }

            $this->db->trans_commit();
            $this->sys_ok("[Success] success update status PO Jasa");
        } 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;
        }
    }
}