<?php
class ReceiveMutasi extends MY_Controller
{
    var $db;
    public function index()
    {
        echo "Receive Mutasi API";
    }

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

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

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

            $start_date = $prm['start_date'];
            $end_date = $prm['end_date'];
            $search = '%' . $prm['search'] . '%';

            $page = 0;
            $limit = 15;
            if ($prm['current_page'] > 0) {
                $page = ($prm['current_page'] - 1) * $limit;
            }

            $status = $prm['status'];
            $status_rm = "";
            if ($status != "") {
                $status_rm .= " AND MutasiHandoverStatus = '{$status}'";
            }

            $sql = "SELECT DISTINCT MutasiHandoverID,
                    MutasiHandoverMutasiRequestID,
                    MutasiHandoverNumber,
                    DATE_FORMAT(MutasiHandoverDate, '%Y-%m-%d') as MutasiHandoverDate,
                    DATE_FORMAT(MutasiHandoverReceiveDate, '%Y-%m-%d') as MutasiHandoverReceiveDate,
                    M_UserUsername,
                    MutasiHandoverReceiveUserID,
                    MutasiHandoverFromBranchID,
                    MutasiHandoverToBranchID,
                    MutasiHandoverStatus,
                    MutasiHandoverNote,
                    MutasiHandoverIsActive,
                    itemCategoryID,
                    itemCategoryName,
                    a.M_BranchID as branch_asal_id,
                    a.M_BranchCode as branch_asal_code,
                    a.M_BranchName as branch_asal_name,
                    b.M_BranchID as branch_tujuan_id,
                    b.M_BranchCode as branch_tujuan_code,
                    b.M_BranchName as branch_tujuan_name,
                    WarehouseID,
                    CASE
                        WHEN WarehouseType = 'B' THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', b.M_BranchName) 
                        ELSE ''
                    END WarehouseName,
                    M_RuanganID,
                    M_RuanganName
                    FROM mutasi_handover
                    JOIN item_category ON MutasiHandoverItemCategoryID = itemCategoryID
                        AND itemCategoryIsActive = 'Y'
                    JOIN m_branch a ON MutasiHandoverFromBranchID = a.M_BranchID
                        AND a.M_BranchIsActive = 'Y'
                    JOIN m_branch b ON MutasiHandoverToBranchID  = b.M_BranchID
                        AND b.M_BranchIsActive = 'Y'
                    LEFT JOIN m_user ON MutasiHandoverReceiveUserID = M_UserID
                    LEFT JOIN warehouse ON MutasiHandoverReceiveWarehouseID = WarehouseID
                        AND WarehouseIsActive = 'Y'
                    LEFT JOIN m_ruangan ON MutasiHandoverReceiveM_RuanganID = M_RuanganID
                        AND M_RuanganIsActive = 'Y'
                    WHERE MutasiHandoverIsActive = 'Y'
                        $status_rm
                        AND (MutasiHandoverNumber LIKE ?)
                        AND DATE(MutasiHandoverDate) BETWEEN DATE(?) AND DATE(?)
                    ORDER BY MutasiHandoverID DESC";

            $sqltotal = "SELECT COUNT(*) as total FROM ($sql) as x";
            $qrytotal = $this->db->query($sqltotal, [$search, $start_date, $end_date]);
            if (!$qrytotal) {
                $this->sys_error_db("['Error'] get total data handover", $this->db);
                exit;
            }
            $total = $qrytotal->row_array()['total'];

            $sqldata = $sql . " LIMIT ? OFFSET ?";
            $qrydata = $this->db->query($sqldata, [
                $search,
                $start_date,
                $end_date,
                $limit,
                $page
            ]);
            if (!$qrydata) {
                $this->sys_error_db("[Error] get list data mutasi", $this->db);
                exit;
            }
            $rows = $qrydata->result_array();

            $result = array(
                "total_page" => ceil($total / $limit),
                "records" => $rows
            );
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

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

            $prm = $this->sys_input;
            $search = '%' . $prm["search"] . '%';

            $sql = "SELECT itemCategoryID,
                itemCategoryName
                FROM item_category
                WHERE itemCategoryIsActive = 'Y'
                AND itemCategoryName LIKE ?
                AND itemCategoryID IN (2,3)
                ORDER BY itemCategoryName ASC";
            $qry = $this->db->query($sql, [$search]);
            if (!$qry) {
                $this->sys_error_db("[Error] Query getCategory");
                return;
            }

            $rows = $qry->result_array();

            $result = array(
                "records" => $rows
            );
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

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

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

            $sql = "SELECT M_BranchID,
                M_BranchCode,
                M_BranchName
                FROM m_branch
                WHERE M_BranchIsActive = 'Y'
                AND M_BranchS_RegionalID = ?";
            $qry = $this->db->query($sql, [$user['S_RegionalID']]);
            if (!$qry) {
                $this->sys_error_db("[Error] Query getBranchAsal");
                return;
            }

            $rows = $qry->result_array();

            $result = array(
                "records" => $rows
            );
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

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

            $prm = $this->sys_input;
            $user = $this->sys_user;
            $search = '%' . $prm["search"] . '%';
            $branchid = $prm['branch_id'];

            $sql = "SELECT M_BranchID,
                M_BranchCode,
                M_BranchName
                FROM m_branch
                WHERE M_BranchIsActive = 'Y'
                AND M_BranchS_RegionalID = ?
                AND M_BranchID = ?
                AND M_BranchName LIKE ?
                ORDER BY M_BranchName ASC";
            $qry = $this->db->query($sql, [$user['S_RegionalID'], $branchid, $search]);
            if (!$qry) {
                $this->sys_error_db("[Error] Query getBranchTujuan");
                return;
            }

            $rows = $qry->result_array();

            $result = array(
                "records" => $rows
            );
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

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

            $prm = $this->sys_input;
            $mutasiHandoverID = $prm['mutasiHandoverID'];

            $sql = "SELECT MutasiHandoverDetailID,
                    MutasiHandoverDetailMutasiHandoverID,
                    MutasiRequestNumber,
                    M_ItemID,
                    M_ItemCode,
                    M_ItemDesc,
                    ItemUnitID,
                    ItemUnitCode,
                    ItemUnitName,
                    WarehouseID,
                    WarehouseName,
                    s.StockID,
                    s.StockQty as stock_total,
                    IFNULL(bc.barcode_total, 0) AS barcode_total,
                    COUNT(DISTINCT lk.MutasiStockLockT_BarcodeBarangID) AS qty_locked,
                    IFNULL(bc.barcode_total, 0) - COUNT(DISTINCT lk.MutasiStockLockT_BarcodeBarangID) AS qty_available,
                    MutasiHandoverDetailQty as qty_mutasi
                    FROM mutasi_handover_detail
                    JOIN mutasi_handover ON MutasiHandoverDetailMutasiHandoverID = MutasiHandoverID
                    JOIN mutasi_request ON MutasiHandoverMutasiRequestID = MutasiRequestID
                    JOIN m_item ON MutasiHandoverDetailM_ItemID = M_ItemID
                    JOIN itemunit ON MutasiHandoverDetailItemUnitID = ItemUnitID
                    JOIN stock s ON MutasiHandoverDetailStockID_From = s.StockID
                    JOIN warehouse w ON s.StockWarehouseID = w.WarehouseID
                        AND w.WarehouseIsActive = 'Y'
                    -- total barcode per stock + PO
                    LEFT JOIN (
                        SELECT
                            b.T_BarcodeBarangStockID,
                            b.T_BarcodeBarangReceiveOrderPoID,
                            COUNT(*) AS barcode_total
                        FROM t_barcode_barang b
                        WHERE b.T_BarcodeBarangIsActive = 'Y'
                        GROUP BY
                            b.T_BarcodeBarangStockID,
                            b.T_BarcodeBarangReceiveOrderPoID
                    ) bc
                        ON bc.T_BarcodeBarangStockID = s.StockID
                        AND bc.T_BarcodeBarangReceiveOrderPoID = MutasiHandoverDetailReceiveOrderPoID
                    -- barcode yang sedang di-lock
                    LEFT JOIN (
                        SELECT
                            l.MutasiStockLockT_BarcodeBarangID,
                            b.T_BarcodeBarangStockID,
                            b.T_BarcodeBarangReceiveOrderPoID
                        FROM mutasi_stock_lock l
                        JOIN t_barcode_barang b
                            ON b.T_BarcodeBarangID = l.MutasiStockLockT_BarcodeBarangID
                        WHERE
                            l.MutasiStockLockIsActive = 'Y'
                            AND l.MutasiStockLockStatus = 'ACTIVE'
                            AND l.MutasiStockLockType = 'INV'
                    ) lk
                        ON lk.T_BarcodeBarangStockID = s.StockID
                        AND lk.T_BarcodeBarangReceiveOrderPoID = MutasiHandoverDetailReceiveOrderPoID
                    WHERE MutasiHandoverDetailIsActive = 'Y'
                    AND MutasiHandoverDetailMutasiHandoverID = ?
                GROUP BY
                    MutasiHandoverDetailID,
                    s.StockID,
                    bc.barcode_total
                ORDER BY
                    MutasiHandoverDetailID";
            $qry = $this->db->query($sql, [$mutasiHandoverID]);
            if (!$qry) {
                $this->sys_error_db("[Error] get item detail", $this->db);
                exit;
            }

            $data = $qry->result_array();

            $result = array(
                "records" => $data
            );

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

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

            $prm = $this->sys_input;
            $branchid = $prm['branch_id'];
            $user = $this->sys_user;
            $whtype = ($user['M_UserLocationFlag'] == 'R') ? 'R' : 'B';

            $sql = "SELECT 
                WarehouseID,
                WarehouseCode,
                CASE
                    WHEN WarehouseType = 'B' THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName) 
                    WHEN WarehouseType = 'R' THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName) 
                    ELSE ''
                END WarehouseName,
                WarehouseType,
                WarehouseIsDefault,
                WarehouseS_RegionalID,
                WarehouseM_BranchID,
                S_RegionalID,
                S_RegionalName
            FROM warehouse 
            JOIN s_regional ON WarehouseS_RegionalID = S_RegionalID AND S_RegionalIsActive = 'Y'
            LEFT JOIN m_branch ON WarehouseM_BranchID = M_BranchID AND M_BranchIsActive = 'Y' 
            WHERE WarehouseS_RegionalID = ? 
                AND WarehouseIsActive = 'Y' AND WarehouseIsTransit = 'N'
                AND WarehouseType = ? AND WarehouseM_BranchID = ? 
            ORDER BY WarehouseName ASC";
            $que = $this->db->query($sql, [
                $user['S_RegionalID'],
                $whtype,
                $branchid
            ]);
            if (!$que) {
                $this->sys_error_db("[Error] get list warehouse");
                exit;
            }
            $data = $que->result_array();
            $this->sys_ok($data);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

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

            $payload = $this->sys_input;
            $branchid = $payload['branch_id'];
            $user = $this->sys_user;
            $search = $payload['search'] . '%';

            $sql = "SELECT M_RuanganID,
                M_RuanganM_BranchID,
                M_RuanganName,
                M_RuanganCode
                FROM m_ruangan
                WHERE M_RuanganIsActive = 'Y'
                AND M_RuanganM_BranchID = ?
                AND M_RuanganName LIKE ?
                ORDER BY M_RuanganName ASC";
            $qry = $this->db->query($sql, [$branchid, $search]);

            if (!$qry) {
                $this->sys_error_db("[Error] query listing ruangan");;
                exit;
            }

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

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

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

            $mutasi_handover_id = $prm['mutasi_handover_id'];
            $warehouse_id = $prm['warehouse_id'];
            $ruangan_id = $prm['ruangan_id'];

            $sql_mutasi_handover = "SELECT MutasiHandoverID,
                    MutasiHandoverMutasiRequestID,
                    MutasiHandoverNumber,
                    MutasiHandoverDate,
                    MutasiHandoverReceiveDate,
                    MutasiHandoverReceiveUserID,
                    MutasiHandoverItemCategoryID,
                    MutasiHandoverFromBranchID,
                    MutasiHandoverToBranchID
                    FROM mutasi_handover
                    WHERE MutasiHandoverIsActive = 'Y'
                    AND MutasiHandoverID = ?";
            $qry_mutasi_handover = $this->db->query($sql_mutasi_handover, [$mutasi_handover_id]);
            if (!$qry_mutasi_handover) {
                $this->sys_error_db("[Error] get mutasi handover", $this->db);
                exit;
            }
            $data_mh = $qry_mutasi_handover->row_array();
            if ($data_mh['MutasiHandoverStatus'] == 'Received') {
                $this->sys_error("Mutasi sudah pernah diterima", $this->db);
                exit;
            }

            $sql_detail_mh = "SELECT MutasiHandoverDetailID,
                    MutasiHandoverDetailMutasiHandoverID,
                    MutasiHandoverDetailMutasiRequestDetailID,
                    MutasiHandoverDetailReceiveOrderPoID,
                    MutasiHandoverDetailM_ItemID,
                    MutasiHandoverDetailItemUnitID,
                    MutasiHandoverDetailStockID_From,
                    MutasiHandoverDetailStockID_To,
                    MutasiHandoverDetailQty,
                    MutasiHandoverDetailBookValue
                    FROM mutasi_handover_detail
                    WHERE MutasiHandoverDetailIsActive = 'Y'
                    AND MutasiHandoverDetailMutasiHandoverID = ?";
            $qry_detail_mh = $this->db->query($sql_detail_mh, [$mutasi_handover_id]);
            if (!$qry_detail_mh) {
                $this->sys_error_db("[Error] get mutasi handover detail", $this->db);
                exit;
            }
            $data_detail_mh = $qry_detail_mh->result_array();

            # Update mutasi handover
            $sql_update_mh = "UPDATE mutasi_handover SET
                    MutasiHandoverReceiveDate = NOW(),
                    MutasiHandoverReceiveUserID = ?,
                    MutasiHandoverReceiveWarehouseID = ?,
                    MutasiHandoverReceiveM_RuanganID = ?,
                    MutasiHandoverStatus = 'Received',
                    MutasiHandoverLastUpdated = NOW(),
                    MutasiHandoverUserID = ?
                    WHERE MutasiHandoverID = ?";
            $qry_update_mh = $this->db->query($sql_update_mh, [
                $user['M_UserID'],
                $warehouse_id,
                $ruangan_id,
                $user['M_UserID'],
                $mutasi_handover_id
            ]);
            if (!$qry_update_mh) {
                $this->db->trans_rollback();
                $this->sys_error_db("Update mutasi handover gagal", $this->db);
                exit;
            }

            foreach ($data_detail_mh as $detail) {
                # Kurangi stock asal
                $sql_upd_stock = "UPDATE stock SET 
                        StockQty = StockQty - ?,
                        StockLastUpdated = NOW(),
                        StockUserID = ?
                    WHERE StockID = ?";
                $qry_upd_stock = $this->db->query($sql_upd_stock, [
                    intval($detail['MutasiHandoverDetailQty']),
                    $user['M_UserID'],
                    $detail['MutasiHandoverDetailStockID_From'],
                ]);
                if (!$qry_upd_stock) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Update stock asal gagal", $this->db);
                    exit;
                }

                # ambil harga dari stock asal
                $sql_cek_price = "SELECT StockItemPrice
                            FROM stock
                            WHERE StockID = ?";
                $qry_cek_price = $this->db->query($sql_cek_price, [
                    $detail['MutasiHandoverDetailStockID_From']
                ]);
                if (!$qry_cek_price) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Cek harga stock asal gagal", $this->db);
                    exit;
                }
                $stock_price_asal = $qry_cek_price->row_array();

                # Cari atau buat stock tujuan
                $sql_cek_stock = "SELECT *
                            FROM stock s
                            JOIN m_item i ON s.StockItemID = i.M_ItemID
                            WHERE s.StockItemID = ?
                            AND s.StockItemUnitID = ?
                            AND s.StockWarehouseID = ?
                            AND i.M_ItemItem_CategoryID = ?";
                $qry_cek_stock = $this->db->query($sql_cek_stock, [
                    $detail['MutasiHandoverDetailM_ItemID'],
                    $detail['MutasiHandoverDetailItemUnitID'],
                    $warehouse_id,
                    $data_mh['MutasiHandoverItemCategoryID']
                ]);
                if (!$qry_cek_stock) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Cek stock tujuan gagal", $this->db);
                    exit;
                }

                $stock_data = $qry_cek_stock->row_array();
                $stock_ID = $stock_data['StockID'];
                $stock_qty_ori = intval($stock_data['StockQty']);
                $stock_qty_price = doubleval($stock_data['StockItemPrice']);
                $stock_qty_end = 0;

                if (!empty($stock_data)) {
                    // calculate stock qty
                    $stock_qty_end = $stock_qty_ori + intval($detail['MutasiHandoverDetailQty']);

                    $sql_update_stock = "UPDATE stock SET 
                            StockItemPrice = ?,
                            StockQty = ?, 
                            StockLastUpdated = NOW(),
                            StockUserID = ?
                        WHERE StockID = ?";
                    $que_update_stock = $this->db->query($sql_update_stock, [
                        $stock_qty_price,
                        $stock_qty_end,
                        $user['M_UserID'],
                        $stock_ID
                    ]);
                    if (!$que_update_stock) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] insert update stock", $this->db);
                        exit;
                    }
                } else {
                    // insert stock baru
                    $sql_insert_stock = "INSERT INTO stock (
                            StockWarehouseAlmariID,
                            StockWarehouseRackID,
                            StockWarehouseID,
                            StockStockNumber,
                            StockItemID,
                            StockItemUnitID,
                            StockItemPrice,
                            StockQty,
                            StockLastUpdated,
                            StockUserID
                        ) VALUES (0,0,?,fn_numbering('SN'),?,?,?,?,NOW(),?)";
                    $que_insert_stock = $this->db->query($sql_insert_stock, [
                        $warehouse_id,
                        $detail['MutasiHandoverDetailM_ItemID'],
                        $detail['MutasiHandoverDetailItemUnitID'],
                        $stock_price_asal['StockItemPrice'],
                        $detail['MutasiHandoverDetailQty'],
                        $user['M_UserID']
                    ]);
                    if (!$que_insert_stock) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] insert new stock");
                        exit;
                    }

                    $stock_ID = $this->db->insert_id();
                    $stock_qty_end = intval($detail['MutasiHandoverDetailQty']);
                }

                # update mutasi_handover_detail stockID_To
                $sql_upd_stock_id_mh = "UPDATE mutasi_handover_detail SET
                        MutasiHandoverDetailStockID_To = ?,
                        MutasiHandoverDetailLastUpdated = NOW(),
                        MutasiHandoverDetailUserID = ?
                        WHERE MutasiHandoverDetailID = ?";
                $qry_upd_stock_id_mh = $this->db->query($sql_upd_stock_id_mh, [
                    $stock_ID,
                    $user['M_UserID'],
                    $detail['MutasiHandoverDetailID']
                ]);
                if (!$qry_upd_stock_id_mh) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Update stockID_To mutasi handover detail gagal", $this->db);
                    exit;
                }

                # insert stock card
                $sql_stock_card = "INSERT INTO stockcard (
                        StockCardWarehouseID,
                        StockCardDatetime,
                        StockCardItemID,
                        StockCardItemUnitID,
                        StockCardReffID,
                        StockCardStatus,
                        StockCardBefore,
                        StockCardIn,
                        StockCardOut,
                        StockCardAfter,
                        StockCardUserID
                    ) VALUES (?, NOW(), ?, ?, ?, 'MRB', ?, ?, 0, ?, ?)";
                $que_stock_card = $this->db->query($sql_stock_card, [
                    $warehouse_id,
                    $detail['MutasiHandoverDetailM_ItemID'],
                    $detail['MutasiHandoverDetailItemUnitID'],
                    $stock_ID,
                    $stock_qty_ori,
                    $detail['MutasiHandoverDetailQty'],
                    $stock_qty_end,
                    $user['M_UserID']
                ]);
                if (!$que_stock_card) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] insert stock card");
                    exit;
                }

                # get barcode untuk nonaktifkan barcode lama #
                $sql_get_barcode = "SELECT MutasiStockLockID,
                            MutasiStockLockT_BarcodeBarangID,
                            MutasiStockLockQtyLocked,
                            MutasiStockLockType
                            FROM mutasi_stock_lock
                            WHERE MutasiStockLockStatus = 'ACTIVE'
                            AND MutasiStockLockIsActive = 'Y'
                            AND MutasiStockLockMutasiRequestID = ?
                            AND MutasiStockLockStockID = ?
                            AND MutasiStockLockM_BranchID = ?";
                $qry_get_barcode = $this->db->query($sql_get_barcode, [
                    $data_mh['MutasiHandoverMutasiRequestID'],
                    $detail['MutasiHandoverDetailStockID_From'],
                    $data_mh['MutasiHandoverFromBranchID']
                ]);
                if (!$qry_get_barcode) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Get stock barcode gagal", $this->db);
                    exit;
                }
                $barcodes = $qry_get_barcode->result_array();

                # cek qty detail vs barcode, qty tidak boleh lebih besar dari barcode
                if (count($barcodes) < intval($detail['MutasiHandoverDetailQty'])) {
                    $this->db->trans_rollback();
                    $this->sys_error("Jumlah barcode tidak mencukupi untuk mutasi");
                    exit;
                }

                # Nonaktifkan barcode lama
                foreach ($barcodes as $bc) {
                    $sql_upd_barcode = "UPDATE t_barcode_barang SET
                            T_BarcodeBarangIsActive = 'N',
                            T_BarcodeBarangUserID = ?,
                            T_BarcodeBarangLastUpdated = NOW()
                            WHERE T_BarcodeBarangID = ?";
                    $qry_upd_barcode = $this->db->query($sql_upd_barcode, [
                        $user['M_UserID'],
                        $bc['MutasiStockLockT_BarcodeBarangID']
                    ]);
                    if (!$qry_upd_barcode) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("Update barcode lama gagal", $this->db);
                        exit;
                    }
                }

                # Generate barcode baru
                if (count($barcodes) > 0) {
                    for ($i = 0; $i < count($barcodes); $i++) {
                        # generate nomor barcode #
                        $noBarcode = $this->generateNoBarcode($user, $ruangan_id, 'BNP', $detail['MutasiHandoverDetailM_ItemID']);

                        # INSERT INTO t_barcode_barang #
                        $sqlInsertBarcode = "INSERT INTO t_barcode_barang(
                                T_BarcodeBarangStockID,
                                T_BarcodeBarangReceiveOrderPoID,
                                T_BarcodeBarangReceiveOrderPoDetailID,
                                T_BarcodeBarangRefID,
                                T_BarcodeBarangRefType,
                                T_BarcodeBarangM_ItemID,
                                T_BarcodeBarangItemUnitID,
                                T_BarcodeBarangNumber,
                                T_BarcodeBarangM_RuanganID,
                                T_BarcodeBarangM_BranchID,
                                T_BarcodeBarangIsActive,
                                T_BarcodeBarangUserID,
                                T_BarcodeBarangCreated) VALUES(?,0,0,?,'MUTASI',?,?,?,?,?,'Y',?,NOW())";
                        $qryInsertBarcode = $this->db->query($sqlInsertBarcode, array(
                            $stock_ID,
                            $mutasi_handover_id,
                            $detail['MutasiHandoverDetailM_ItemID'],
                            $detail['MutasiHandoverDetailItemUnitID'],
                            $noBarcode,
                            $ruangan_id,
                            $data_mh['MutasiHandoverToBranchID'],
                            $user['M_UserID']
                        ));
                        if (!$qryInsertBarcode) {
                            $this->db->trans_rollback();
                            $this->sys_error_db("[Error] insert data barcode item");
                            exit;
                        }
                    }
                }

                # CONSUMED LOCK STOCK
                $sql_consumed_lock = "UPDATE mutasi_stock_lock SET
                            MutasiStockLockStatus = 'CONSUMED',
                            MutasiStockLockLastUpdated = NOW(),
                            MutasiStockLockUserID = ?
                            WHERE MutasiStockLockMutasiRequestDetailID = ?
                            AND MutasiStockLockStatus = 'ACTIVE'
                            AND MutasiStockLockType = 'INV'
                            AND MutasiStockLockIsActive = 'Y'";
                $qry_consumed_lock = $this->db->query($sql_consumed_lock, [
                    $user['M_UserID'],
                    $detail['MutasiHandoverDetailMutasiRequestDetailID']
                ]);
                if (!$qry_consumed_lock) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("Update lock stock gagal", $this->db);
                    exit;
                }
            }

            // UPDATE STATUS
            $sql_upd_handover = "UPDATE mutasi_handover
                        SET MutasiHandoverStatus = 'Received',
                            MutasiHandoverReceiveDate = NOW(),
                            MutasiHandoverReceiveUserID = ?,
                            MutasiHandoverReceiveWarehouseID = ?,
                            MutasiHandoverReceiveM_RuanganID = ?
                        WHERE MutasiHandoverID = ?";
            $qry_upd_handover = $this->db->query($sql_upd_handover, [
                $user['M_UserID'],
                $warehouse_id,
                $ruangan_id,
                $data_mh['MutasiHandoverID']
            ]);
            if (!$qry_upd_handover) {
                $this->db->trans_rollback();
                $this->sys_error_db("Update status mutasi handover gagal", $this->db);
                exit;
            }

            // LOG MUTASI HANDOVER
            $sql_get_header = "SELECT * FROM mutasi_handover WHERE MutasiHandoverID = ?";
            $qry_get_header = $this->db->query($sql_get_header, [$data_mh['MutasiHandoverID']]);
            if (!$qry_get_header) {
                $this->db->trans_rollback();
                $this->sys_error_db("Get header handover gagal", $this->db);
                exit;
            }
            $header_handover = $qry_get_header->row_array();

            $sql_get_detail = "SELECT * FROM mutasi_handover_detail WHERE MutasiHandoverDetailMutasiHandoverID = ? AND MutasiHandoverDetailIsActive = 'Y'";
            $qry_get_detail = $this->db->query($sql_get_detail, [$data_mh['MutasiHandoverID']]);
            if (!$qry_get_detail) {
                $this->db->trans_rollback();
                $this->sys_error_db("Get detail handover gagal", $this->db);
                exit;
            }
            $detail_handover = $qry_get_detail->result_array();
            $header_handover['details'] = $detail_handover;

            $this->insertUserActivity('MH', "Received data mutasi handover ID : {$header_handover['MutasiHandoverID']}", 'RECEIVED', $header_handover['MutasiHandoverID'], $header_handover, $user['M_UserID']);

            # get data before
            $dataMrBefore = $this->getDataMutasiRequest($data_mh['MutasiHandoverMutasiRequestID']);

            $sql_upd_request = "UPDATE mutasi_request
                        SET MutasiRequestStatus = 'Received',
                        MutasiRequestLastUpdated = NOW(),
                        MutasiRequestUserID = ?
                        WHERE MutasiRequestID = ?";
            $qry_upd_request = $this->db->query($sql_upd_request, [
                $user['M_UserID'],
                $data_mh['MutasiHandoverMutasiRequestID']
            ]);
            if (!$qry_upd_request) {
                $this->db->trans_rollback();
                $this->sys_error_db("Update status mutasi request gagal", $this->db);
                exit;
            }

            $dataMrAfter = $this->getDataMutasiRequest($data_mh['MutasiHandoverMutasiRequestID']);
            $this->insertLogMutasiRequest($data_mh['MutasiHandoverMutasiRequestID'], 'RECEIVED', $dataMrBefore, $dataMrAfter, $user['M_UserID'], "Received data mutasi request by user ID : {$user['M_UserID']}");
            $this->insertUserActivity('MR', "Received data mutasi request by user ID : {$user['M_UserID']}", 'RECEIVED', $data_mh['MutasiHandoverMutasiRequestID'], '', $user['M_UserID']);

            $this->db->trans_commit();
            $this->sys_ok("Mutasi berhasil diterima");
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

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

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

            $sql = "SELECT 
                T_BarcodeBarangID as id,
                T_BarcodeBarangNumber,
                M_ItemDesc,
                M_BranchName,
                M_RuanganName,
                'N' as chex
                FROM t_barcode_barang 
                JOIN m_item ON M_ItemID = T_BarcodeBarangM_ItemID
                JOIN m_branch ON M_BranchID = T_BarcodeBarangM_BranchID
                LEFT JOIN m_ruangan ON M_RuanganID = T_BarcodeBarangM_RuanganID
                WHERE T_BarcodeBarangRefID = ?
                AND T_BarcodeBarangIsActive = 'Y'
                ORDER BY T_BarcodeBarangID";
            $que = $this->db->query($sql, [$mutasi_handover_id]);
            if (!$que) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get barcodes");
                exit;
            }

            $barcodes = $que->result_array();
            if ($barcodes) {
                foreach ($barcodes as $k => $v) {
                    if ($v['chex'] == 'N')
                        $barcodes[$k]['chex'] = false;
                    else
                        $barcodes[$k]['chex'] = true;
                }
            }
            $this->db->trans_commit();
            $this->sys_ok($barcodes);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }


    // ------------------------------------------------- PRIVATE FUNCTION ----------------------------------------------- //
    private function generateNoBarcode($user, $lokasiID, $typeBarcode, $itemid)
    {
        $branchid = ($user['loginLevel'] == 'branch') ? $user['M_BranchID'] : 0;

        if ($user['loginlevel'] == 'regional') {
            $this->db->trans_rollback();
            $this->sys_error('Tidak bisa generare No Barcode, anda login sebagai regional');
            exit;
        }

        // -- numtype = tipe numbering
        // -- itemid = id item inventaris/asset
        // -- branchid = id cabang
        // -- ruanganid = id ruangan di cabang

        $sqlnum = "SELECT `fn_num_nonpersediaan`(?, ?, ?, ?) AS numpd;";
        $quenum = $this->db->query($sqlnum, [$typeBarcode, $itemid, $branchid, $lokasiID]);

        if (!$quenum) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] generate number Barcode");
            exit;
        }

        $numPL = $quenum->row_array()['numpd'];
        if (!isset($numPL)) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] number Barcode null");
            exit;
        }

        return $numPL;
    }

    private function getDataMutasiRequest($id)
    {
        $sql = "SELECT * FROM mutasi_request WHERE MutasiRequestID = ?";
        $qry = $this->db->query($sql, [$id]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] get mutasi request", $this->db);
            exit;
        }
        $header = $qry->row_array();

        $sqldetail = "SELECT * FROM mutasi_request_detail 
        WHERE MutasiRequestDetailMutasiRequestID = ? AND MutasiRequestDetailIsActive = 'Y'";
        $qrydetail = $this->db->query($sqldetail, [$id]);
        if (!$qrydetail) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] get mutasi request detail", $this->db);
            exit;
        }
        $detail = $qrydetail->result_array();
        $header['details'] = $detail;
        return $header;
    }

    // 
    private function insertUserActivity(
        $code,
        $user_desc = '',
        $status,
        $reff_id,
        $data = '',
        $userId
    ) {
        $sql_log = "INSERT INTO user_activity(
                    UserActivityCode,
                    UserActivityStatus,
                    UserActivityDescription,
                    UserActivityRefID,
                    UserActivityData,
                    UserActivityUserID,
                    UserActivityCreated
                    ) VALUES(?,?,?,?,?,?,NOW())";
        $qry_log = $this->db->query($sql_log, [
            $code,
            $status,
            $user_desc,
            $reff_id,
            !empty($data) ? json_encode($data) : '',
            $userId
        ]);
        if (!$qry_log) {
            $this->db->trans_rollback();
            $this->sys_error_db("insert log", $this->db);
            exit;
        }
    }

    private function insertLogMutasiRequest(
        $id,
        $type,
        $dataBefore,
        $dataAfter,
        $userID,
        $desc = ''
    ) {
        $sql = "INSERT INTO acc_one_log.mutasi_request_log(
                MutasiRequestLogMutasiRequestID,
                MutasiRequestLogType,
                MutasiRequestLogDesc,
                MutasiRequestLogJsonBefore,
                MutasiRequestLogJsonAfter,
                MutasiRequestLogUserID,
                MutasiRequestLogCreated
                ) VALUES(?,?,?,?,?,?,NOW())";
        $qry = $this->db->query($sql, [
            $id,
            $type,
            $desc,
            !empty($dataBefore) ? json_encode($dataBefore) : '',
            !empty($dataAfter) ? json_encode($dataAfter) : '',
            $userID
        ]);
        if (!$qry) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] insert log mutasi request", $this->db);
            exit;
        }
    }
}
