<?php
class PurchaseRequestListing extends MY_Controller
{
    var $db;
    public function index()
    {
        echo "LISTING PURCHASE REQUEST";
    }

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

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

            $para = $this->sys_input;
            $startdate = $para["startdate"];
            $enddate = $para["enddate"];
            $regional = $para["regional"];

            $branch = $para['branch'];
            $cabang = "";
            if ($branch == "ALL" || $branch == "") {
                $cabang = "%%";
            } else {
                $cabang = "%" . $branch . "%";
            }

            $f_stat = [];
            $status = $para["status"];
            switch ($status) {
                case 'READ':
                    $f_stat = ["Read", "X"];
                    break;
                case 'NEW':
                    $f_stat = ["Approved", "X"];
                    break;
                default:
                    $f_stat = ["Approved", "Read"];
                    break;
            }

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

            $sqltotal = "SELECT COUNT(DISTINCT PurchaseRequestDetailID) as total
                FROM purchase_request
                JOIN purchase_request_detail ON PurchaseRequestDetailPurchaseRequestID = PurchaseRequestID
                    AND PurchaseRequestDetailIsActive = 'Y'
                JOIN s_regional ON S_RegionalID = PurchaseRequestS_RegionalID 
                    AND S_RegionalIsActive = 'Y'
                JOIN m_item ON M_ItemID = PurchaseRequestDetailM_ItemID
                    AND M_ItemIsActive = 'Y'
                LEFT JOIN m_branch ON M_BranchCode = PurchaseRequestM_BranchCode 
                    AND M_BranchIsActive = 'Y'
                LEFT JOIN warehouse ON WarehouseS_RegionalID = PurchaseRequestS_RegionalID 
                    AND WarehouseIsActive = 'Y'
                    AND (WarehouseIsTransit != 'Y' OR WarehouseIsTransit IS NULL)
                LEFT JOIN stock ON StockItemId = M_ItemID
                    AND StockWarehouseID = warehouse.WarehouseID
                LEFT JOIN purchase_request_flag ON PurchaseRequestFlagPurchaseRequestDetailID = PurchaseRequestDetailID
                    AND PurchaseRequestFlagIsActive = 'Y'
                    AND PurchaseRequestFlagIsClosed = 'N'
                WHERE PurchaseRequestDetailStatus IN (?,?)
                    AND PurchaseRequestDate >= DATE(?)
                    AND PurchaseRequestDate <= DATE(?)
                    AND PurchaseRequestS_RegionalID = ?
                    AND (? = '%%' OR 
                        (PurchaseRequestM_BranchCode LIKE ? OR 
                        (PurchaseRequestM_BranchCode IS NULL AND 
                        ? = '%%')))
                -- GROUP BY PurchaseRequestDetailID
                ORDER BY
                    PurchaseRequestDetailStatus ASC,
                    PurchaseRequestDetailID DESC, 
                    PurchaseRequestDate DESC,
                    PurchaseRequestFlagID DESC
                    ";
            $qrytot = $this->db->query($sqltotal, [
                $f_stat[0],
                $f_stat[1],
                $startdate,
                $enddate,
                $regional,
                $cabang,
                $cabang,
                $cabang
            ]);
            $total = $qrytot->result_array()[0]['total'];

            $sqldata = "SELECT 
                    COALESCE(PurchaseRequestFlagID, 'new') as PurchaseRequestFlagID,
                    PurchaseRequestDate, PurchaseRequestNumber,
                    S_RegionalID, S_RegionalName, 
                    COALESCE(M_BranchCode, '') AS M_BranchCode, 
                    COALESCE(M_BranchName, '') AS M_BranchName,
                    PurchaseRequestDetailID, M_ItemID,
                    PurchaseRequestDetailIsCito,
                    M_ItemDesc, PurchaseRequestDetailQty,
                    COALESCE(SUM(CASE WHEN warehouse.WarehouseID IS NOT NULL AND stock.StockItemId IS NOT NULL THEN stock.StockQty ELSE 0 END), 0) as StockQty,
                    COALESCE(warehouse.WarehouseID, '') as StockWarehouseID,
                    PurchaseRequestDetailStatus,
                    COALESCE(PurchaseRequestFlagStatus, '') as PurchaseRequestFlagStatus 
                FROM purchase_request
                JOIN purchase_request_detail ON PurchaseRequestDetailPurchaseRequestID = PurchaseRequestID
                    AND PurchaseRequestDetailIsActive = 'Y'
                JOIN s_regional ON S_RegionalID = PurchaseRequestS_RegionalID 
                    AND S_RegionalIsActive = 'Y'
                JOIN m_item ON M_ItemID = PurchaseRequestDetailM_ItemID
                    AND M_ItemIsActive = 'Y'
                LEFT JOIN m_branch ON M_BranchCode = PurchaseRequestM_BranchCode 
                    AND M_BranchIsActive = 'Y'
                LEFT JOIN warehouse ON WarehouseS_RegionalID = PurchaseRequestS_RegionalID 
                    AND WarehouseIsActive = 'Y'
                    AND (WarehouseIsTransit != 'Y' OR WarehouseIsTransit IS NULL)
                LEFT JOIN stock ON StockItemId = M_ItemID
                    AND StockWarehouseID = warehouse.WarehouseID
                LEFT JOIN purchase_request_flag ON PurchaseRequestFlagPurchaseRequestDetailID = PurchaseRequestDetailID
                    AND PurchaseRequestFlagIsActive = 'Y'
                    AND PurchaseRequestFlagIsClosed = 'N'
                WHERE PurchaseRequestDetailStatus IN (?,?)
                    AND PurchaseRequestDate >= DATE(?)
                    AND PurchaseRequestDate <= DATE(?)
                    AND PurchaseRequestS_RegionalID = ?
                    AND (? = '%%' OR 
                        (PurchaseRequestM_BranchCode LIKE ? OR 
                        (PurchaseRequestM_BranchCode IS NULL AND 
                        ? = '%%')))
                GROUP BY PurchaseRequestDetailID
                ORDER BY PurchaseRequestDetailStatus ASC,
                    PurchaseRequestDetailID DESC,
                    PurchaseRequestDate DESC,
                    PurchaseRequestFlagID DESC
                LIMIT ? OFFSET ?";
            $qrydata = $this->db->query($sqldata, [
                $f_stat[0],
                $f_stat[1],
                $startdate,
                $enddate,
                $regional,
                $cabang,
                $cabang,
                $cabang,
                $limit,
                $page
            ]);
            $data = $qrydata->result_array();

            $result = array(
                "records" => $data,
                "total" => $total
            );
            $this->sys_ok($result);
        } catch (Exception $ex) {
            $message = $ex->getMessage();
            $this->sys_error($message);
        }
    }

    /** 
     * Refactor 18 Juni 2025 by Mario
     * Whats new:
     * > Perhitungan stok mempertimbangkan:
     * > - Stock hanya diambil dari gudang regional
     * > - Stock hanya diambil dari gudang default (untuk handle kasus jakarta ada 2 gudang regional)
     * > - Mempertimbangkan unitItem sebelum menjumlahkan kuantitas stok karena ada PR dengan unit berbeda
     * > - Menghitung stok dengan subquery daripada join
     * > - Memperhatikan StockED untuk ItemCategoryID == 1 (Persediaan), jika ItemID dan ItemUnitID sama maka jumlah semua stok dari Gudang Regional selama StockED >= hari ini
     */
    public function list_purchaserequest()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit;
            }

            $para = $this->sys_input;
            $startdate = $para["startdate"];
            $enddate = $para["enddate"];
            $regional = $para["regional"];

            $branch = $para['branch'];
            $cabang = "";
            if ($branch == "ALL" || $branch == "") {
                $cabang = "%%";
            } else {
                $cabang = "%" . $branch . "%";
            }

            $f_stat = [];
            $status = $para["status"];
            switch ($status) {
                case 'READ':
                    $f_stat = ["Read", "X"];
                    break;
                case 'NEW':
                    $f_stat = ["Approved", "X"];
                    break;
                default:
                    $f_stat = ["Approved", "Read"];
                    break;
            }

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

            $sqltotal = "SELECT COUNT(DISTINCT PurchaseRequestDetailID) as total
                FROM purchase_request_detail
                JOIN purchase_request ON PurchaseRequestDetailPurchaseRequestID = PurchaseRequestID
                    AND PurchaseRequestDetailIsActive = 'Y'
                JOIN s_regional ON S_RegionalID = PurchaseRequestS_RegionalID 
                    AND S_RegionalIsActive = 'Y'
                JOIN m_item ON M_ItemID = PurchaseRequestDetailM_ItemID
                    AND M_ItemIsActive = 'Y'
                LEFT JOIN m_branch ON M_BranchCode = PurchaseRequestM_BranchCode 
                    AND M_BranchIsActive = 'Y'
                LEFT JOIN itemunit unit_req ON unit_req.ItemUnitID = PurchaseRequestDetailItemUnitID
                    AND unit_req.ItemUnitIsActive = 'Y'
                LEFT JOIN purchase_request_flag ON PurchaseRequestFlagPurchaseRequestDetailID = PurchaseRequestDetailID
                    AND PurchaseRequestFlagIsActive = 'Y'
                    AND PurchaseRequestFlagIsClosed = 'N'
                WHERE PurchaseRequestDetailStatus IN (?,?)
                    AND PurchaseRequestDate >= DATE(?)
                    AND PurchaseRequestDate <= DATE(?)
                    AND PurchaseRequestS_RegionalID = ?
                    AND (? = '%%' OR 
                        (PurchaseRequestM_BranchCode LIKE ? OR 
                        (PurchaseRequestM_BranchCode IS NULL AND 
                        ? = '%%')))";
            $qrytot = $this->db->query($sqltotal, [
                $f_stat[0],
                $f_stat[1],
                $startdate,
                $enddate,
                $regional,
                $cabang,
                $cabang,
                $cabang
            ]);
            $total = $qrytot->result_array()[0]['total'];

            $sqldata = "SELECT 
                COALESCE(PurchaseRequestFlagID, 'new') as PurchaseRequestFlagID,
                PurchaseRequestDate, PurchaseRequestNumber,
                S_RegionalID, S_RegionalName, 
                COALESCE(M_BranchCode, '') AS M_BranchCode, 
                COALESCE(M_BranchName, '') AS M_BranchName,
                PurchaseRequestDetailID, M_ItemID,
                PurchaseRequestDetailIsCito,
                M_ItemDesc, PurchaseRequestDetailQty,
                unit_req.ItemUnitName AS UnitRequest,
                unit_req.ItemUnitID AS UnitIDRequest,
                PurchaseRequestDetailStatus,
                COALESCE(PurchaseRequestFlagStatus, '') as PurchaseRequestFlagStatus
            FROM purchase_request_detail
            JOIN purchase_request ON PurchaseRequestDetailPurchaseRequestID = PurchaseRequestID
                AND PurchaseRequestDetailIsActive = 'Y'
            JOIN s_regional ON S_RegionalID = PurchaseRequestS_RegionalID 
                AND S_RegionalIsActive = 'Y'
            LEFT JOIN m_branch ON M_BranchCode = PurchaseRequestM_BranchCode 
                AND M_BranchIsActive = 'Y'
            JOIN m_item ON M_ItemID = PurchaseRequestDetailM_ItemID
                AND M_ItemIsActive = 'Y'
            JOIN itemunit unit_req ON unit_req.ItemUnitID = PurchaseRequestDetailItemUnitID
                AND unit_req.ItemUnitIsActive = 'Y'
            LEFT JOIN warehouse ON WarehouseS_RegionalID = PurchaseRequestS_RegionalID 
                AND WarehouseIsActive = 'Y'
                AND (WarehouseIsTransit != 'Y' OR WarehouseIsTransit IS NULL)
                AND WarehouseM_BranchID = 0
                AND WarehouseIsDefault = 'Y'
            LEFT JOIN purchase_request_flag ON PurchaseRequestFlagPurchaseRequestDetailID = PurchaseRequestDetailID
                AND PurchaseRequestFlagIsActive = 'Y'
                AND PurchaseRequestFlagIsClosed = 'N'
            WHERE PurchaseRequestDetailStatus IN (?,?)
                AND PurchaseRequestDate >= DATE(?)
                AND PurchaseRequestDate <= DATE(?)
                AND PurchaseRequestS_RegionalID = ?
                AND (? = '%%' OR 
                    (PurchaseRequestM_BranchCode LIKE ? OR 
                    (PurchaseRequestM_BranchCode IS NULL AND 
                    ? = '%%')))
            ORDER BY PurchaseRequestDetailStatus ASC,
                PurchaseRequestDetailID DESC,
                PurchaseRequestDate DESC,
                PurchaseRequestFlagID DESC
            LIMIT ? OFFSET ?";
            $qrydata = $this->db->query($sqldata, [
                $f_stat[0],
                $f_stat[1],
                $startdate,
                $enddate,
                $regional,
                $cabang,
                $cabang,
                $cabang,
                $limit,
                $page
            ]);
            if (!$qrydata) {
                throw new Exception(json_encode($this->db->error()));
            }
            
            // TODO: Hapus Last Query jika tidak diperlukan
            // $lastQuery = $this->db->last_query();
            $data = $qrydata->result_array();

            // For each PR Detail, fetch the stock data across all units
            foreach ($data as &$row) {
                $stockSql = "SELECT 
                    SUM(s.StockQty) as QtyTotal,
                    u.ItemUnitName,
                    s.StockItemUnitID
                FROM stock s
                JOIN warehouse w ON s.StockWarehouseID = w.WarehouseID
                JOIN itemunit u ON s.StockItemUnitID = u.ItemUnitID
                WHERE s.StockItemId = ?
                AND w.WarehouseS_RegionalID = ?
                AND w.WarehouseIsActive = 'Y'
                AND (w.WarehouseIsTransit != 'Y' OR w.WarehouseIsTransit IS NULL)
                AND w.WarehouseM_BranchID = 0
                AND w.WarehouseIsDefault = 'Y'
                AND (
                    ? != 1 
                    OR (? = 1 AND (s.StockED IS NULL OR s.StockED >= CURDATE()))
                )
                GROUP BY s.StockItemUnitID, u.ItemUnitName";
                
                $stockQry = $this->db->query($stockSql, [
                    $row['M_ItemID'],
                    $row['S_RegionalID'],
                    $row['PurchaseRequestItemCategoryID'] ?? 0,
                    $row['PurchaseRequestItemCategoryID'] ?? 0
                ]);

                if (!$stockQry) {
                    throw new Exception(json_encode($this->db->error()));
                }

                // Kalau item belum ada di stock, returnnya []
                
                $row['StockQtyArray'] = $stockQry->result_array();
            }

            $result = array(
                "records" => $data,
                // "lastQuery" => $lastQuery,
                "total" => $total
            );
            $this->sys_ok($result);
        } catch (Exception $ex) {
            $message = $ex->getMessage();
            $this->sys_error($message);
        }
    }

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

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

            $sql = "SELECT S_RegionalID, S_RegionalName 
            FROM s_regional WHERE S_RegionalIsActive = 'Y' AND S_RegionalName LIKE ?";
            $query = $this->db->query($sql, [$search]);
            if (!$query) {
                $this->sys_error_db("error get listing regional");
                exit;
            }

            $rows = $query->result_array();
            $result = array(
                "records" => $rows,
                "total" => sizeof($rows)
            );
            $this->sys_ok($result);
        } catch (Exception $ex) {
            $message = $ex->getMessage();
            $this->sys_error($message);
        }
    }

    public function listing_branch()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit;
            }
            $prm = $this->sys_input;
            $regID = $prm['regionalID'];

            $sql = "SELECT
                M_BranchCode,
                M_BranchName
                FROM m_branch
                WHERE M_BranchS_RegionalID = ? AND M_BranchIsActive = 'Y'";
            $query = $this->db->query($sql, [$regID]);
            if (!$query) {
                $this->sys_error_db("error get branch based on regional");
                exit;
            }

            $rows = $query->result_array();
            $result = array(
                "result" => $rows,
                "total" => sizeof($rows)
            );
            $this->sys_ok($result);
        } catch (Exception $ex) {
            $message = $ex->getMessage();
            $this->sys_error($message);
        }
    }

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

            $this->db->trans_begin();
            $userid = $this->sys_user["M_UserID"];
            $prm = $this->sys_input;
            $reqnumber = $prm['reqnumber'];
            $reqdetailid = $prm['reqdetailid'];
            $regionalid = $prm['regionalid'];
            $branchcode = $prm['branchcode'];
            $qty = $prm['qty'];
            $stock = $prm['stock'];
            $status = $prm['status'];
            $UnitIDRequest = $prm['UnitIDRequest'];

            /* Validasi ItemUnit Request dengan Stock */
            $stock = $this->calculateStockByItemUnitReq($stock, $UnitIDRequest);

            $sqlin = "INSERT INTO purchase_request_flag (
                PurchaseRequestFlagPurchaseRequestDetailID,
                PurchaseRequestFlagS_RegionalID,
                PurchaseRequestFlagM_BranchCode,
                PurchaseRequestFlagQty,
                PurchaseRequestFlagQtyRest,
                PurchaseRequestFlagStatus,
                PurchaseRequestFlagUserID,
                PurchaseRequestFlagCreated
            ) VALUES (?,?,?,?,?,?,?,NOW())";
            $query = $this->db->query($sqlin, [
                $reqdetailid,
                $regionalid,
                $branchcode,
                $qty,
                $qty,
                $status,
                $userid
            ]);
            if (!$query) {
                $this->db->trans_rollback();
                $this->sys_error_db("error insert status request");
                exit;
            }

            $reqflagid = $this->db->insert_id();
            $sqlget = "SELECT * FROM purchase_request_flag WHERE PurchaseRequestFlagID = ?";
            $queget = $this->db->query($sqlget, [$reqdetailid]);
            if (!$queget) {
                $this->db->trans_rollback();
                $this->sys_error_db("error get latest inserted flag");
                exit;
            }
            $data = $queget->result_array()[0];
            $json = json_encode($data);

            $sqlog = "INSERT INTO acc_one_log.purchaserequestflag_log (
                PurchaseRequestFlagLogPurchaseRequestFlagID,
                PurchaseRequestFlagLogStatus,
                PurchaseRequestFlagLogQty,
                PurchaseRequestFlagLogStock,
                PurchaseRequestFlagLogJson,
                PurchaseRequestFlagLogUserID,
                PurchaseRequestFlagLogCreated
            ) VALUES (?, ?, ?, ?, ?, ?, NOW())";
            $quelog = $this->db->query($sqlog, [$reqflagid, $status, $qty, $stock, $json, $userid]);
            if (!$quelog) {
                $this->db->trans_rollback();
                $this->sys_error_db("error insert log purchase request flag");
                exit;
            }

            $sqlread = "UPDATE purchase_request_detail SET
                PurchaseRequestDetailStatus = 'Read'
            WHERE PurchaseRequestDetailID = ?";
            $queread = $this->db->query($sqlread, [$reqdetailid]);
            if (!$queread) {
                $this->db->trans_rollback();
                $this->sys_error_db("error update status purchase request detail to read");
                exit;
            }

            $sqlpart = "UPDATE purchase_request SET
            PurchaseRequestStatus = 'Partial'
            WHERE PurchaseRequestRefNumber = ?";
            $quepart = $this->db->query($sqlpart, [$reqnumber]);
            if (!$quepart) {
                $this->db->trans_rollback();
                $this->sys_error_db("error update status purchase request to partial");
                exit;
            }

            $this->db->trans_commit();
            $this->sys_ok("Success insert status request");

        } catch (\Throwable $ex) {
            $message = $ex->getMessage();
            $this->sys_error($message);
        }
    }

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

            $this->db->trans_begin();
            $userid = $this->sys_user["M_UserID"];
            $prm = $this->sys_input;

            $reqnumber = $prm['reqnumber'];
            $reqflagid = $prm['requestflagid'];
            $reqdetailid = $prm['reqdetailid'];
            $regionalid = $prm['regionalid'];
            $branchcode = $prm['branchcode'];
            $reqqty = $prm['qty'];
            $reqstock = $prm['stock'];
            $reqstatus = $prm['status'];
            $UnitIDRequest = $prm['UnitIDRequest'];

             /* Validasi ItemUnit Request dengan Stock */
             $stock = $this->calculateStockByItemUnitReq($reqstock, $UnitIDRequest);

            $sqlcha = "UPDATE purchase_request_flag SET
                PurchaseRequestFlagPurchaseRequestDetailID = ?,
                PurchaseRequestFlagS_RegionalID = ?,
                PurchaseRequestFlagM_BranchCode = ?,
                PurchaseRequestFlagQty = ?,
                PurchaseRequestFlagQtyRest = ?,
                PurchaseRequestFlagStatus = ?,
                PurchaseRequestFlagUserID = ?,
                PurchaseRequestFlagLastUpdated = NOW()
            WHERE PurchaseRequestFlagID = ?";
            $query = $this->db->query($sqlcha, [
                $reqdetailid,
                $regionalid,
                $branchcode,
                $reqqty,
                $reqqty,
                $reqstatus,
                $userid,
                $reqflagid
            ]);
            if (!$query) {
                $this->db->trans_rollback();
                $this->sys_error_db("error update status flag requset");
                exit;
            }

            $sqlget = "SELECT * FROM purchase_request_flag WHERE PurchaseRequestFlagID = ?";
            $queget = $this->db->query($sqlget, [$reqflagid]);
            if (!$queget) {
                $this->db->trans_rollback();
                $this->sys_error_db("error get data change");
                exit;
            }
            $data = $queget->result_array()[0];
            $json = json_encode($data);

            $sqlog = "INSERT INTO acc_one_log.purchaserequestflag_log (
                PurchaseRequestFlagLogPurchaseRequestFlagID,
                PurchaseRequestFlagLogStatus,
                PurchaseRequestFlagLogQty,
                PurchaseRequestFlagLogStock,
                PurchaseRequestFlagLogJson,
                PurchaseRequestFlagLogUserID,
                PurchaseRequestFlagLogCreated
            ) VALUES (?, ?, ?, ?, ?, ?, NOW())";
            $quelog = $this->db->query($sqlog, [$reqflagid, $reqstatus, $reqqty, $stock, $json, $userid]);
            if (!$quelog) {
                $this->db->trans_rollback();
                $this->sys_error_db("error insert log purchase request flag");
                exit;
            }

            $this->db->trans_commit();
            $this->sys_ok("success");
        } catch (\Throwable $ex) {
            $message = $ex->getMessage();
            $this->sys_error($message);
        }
    }

    private function calculateStockByItemUnitReq(array $stock, string $UnitIDRequest): int
    {
        // Cek $stock empty array atau tidak, jika iya $stok = 0
        if (!is_array($stock) || empty($stock)) {
            return 0;
        }

        // Cari object di $stock di mana StockItemUnitID == $UnitIDRequest,
        // Jika tidak ada, set $stock = 0
        $equivalentStock = array_filter($stock, function ($item) use ($UnitIDRequest) {
            return $item['StockItemUnitID'] == $UnitIDRequest;
        });

        if (empty($equivalentStock)) {
            return 0;
        }

        return array_values($equivalentStock)[0]['QtyTotal'] ?? 0;
    }
}