<?php

class PurchaseRequestDirectApproved extends MY_Controller
{
    var $db;

    public function index()
    {
        echo "Purchase Request/Manager API";
    }

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

    function search()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }

            $payload = $this->sys_input;
            $user = $this->sys_user;
            $regionalID = $user['S_RegionalID'];
            $branchCode = $user['M_BranchCode'];
            $loginType = $user['M_UserLocationFlag'];
            $userID = $user['M_UserID'];
            $sql = "SELECT m_approve_level.* FROM m_user
                JOIN m_approve_level
                ON M_UserM_ApproveLevelID = M_ApproveLevelID
                WHERE M_UserID = ?;";
            $qry = $this->db->query($sql, [$userID]);
            if (!$qry) {
                $this->sys_error_db("Error cek approval level");
                exit;
            }
            $approvalLevel = $qry->result_array();
            if (count($approvalLevel) == 0) {
                $result = array(
                    'total' => 0,
                    'records' => []
                );
                $this->sys_ok($result);
                exit;
            }

            $totalStart = $approvalLevel[0]['M_ApproveLevelStartTotal'];
            $totalEnd = $approvalLevel[0]['M_ApproveLevelEndTotal'];
            $query = "SELECT prd.*, mu.M_UserUsername as M_RequesterFullName
                      FROM purchase_request_direct as prd
                      JOIN m_user as mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                      WHERE PurchaseRequestDirectStatus != 'Draft'
                      AND PurchaseRequestDirectIsActive = 'Y'
                      AND PurchaseRequestDirectTotalEstimation BETWEEN $totalStart AND $totalEnd
                      AND PurchaseRequestDirectNumber LIKE '%" . $payload["search"] . "%'";
            $queryCount = "SELECT count(*) as total
                           FROM purchase_request_direct as prd
                           JOIN m_user as mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                           WHERE PurchaseRequestDirectStatus != 'Draft'
                           AND PurchaseRequestDirectIsActive = 'Y'
                           AND PurchaseRequestDirectTotalEstimation BETWEEN $totalStart AND $totalEnd
                           AND PurchaseRequestDirectNumber LIKE '%" . $payload["search"] . "%'";

            if ((isset($payload["startDate"]) && isset($payload["endDate"])) && (trim($payload["startDate"]) !== "" && trim($payload["endDate"]) !== "")) {
                $query .= " AND (PurchaseRequestDirectDate BETWEEN '{$payload["startDate"]} 00:00:00' AND '{$payload["endDate"]} 23:59:59' OR PurchaseRequestDirectDateUse BETWEEN '{$payload["startDate"]} 00:00:00' AND '{$payload["endDate"]} 23:59:59')";
                $queryCount .= " AND (PurchaseRequestDirectDate BETWEEN '{$payload["startDate"]} 00:00:00' AND '{$payload["endDate"]} 23:59:59' OR PurchaseRequestDirectDateUse BETWEEN '{$payload["startDate"]} 00:00:00' AND '{$payload["endDate"]} 23:59:59')";
            }

            if ($payload["status"]) {
                $query .= " AND PurchaseRequestDirectStatus = '{$payload["status"]}'";
                $queryCount .= " AND PurchaseRequestDirectStatus = '{$payload["status"]}'";
            }

            $exec  = $this->db->query($queryCount, []);

            $numberLimit = 5;
            $numberOffset = 0;
            if ($payload["currentPage"] > 0) {
                $numberOffset = ($payload["currentPage"] - 1) * $numberLimit;
            }

            $totalCount = 0;
            $totalPage = 0;

            if ($exec) {
                $totalCount = $exec->result_array()[0]["total"];
                $totalPage = ceil($totalCount / $numberLimit);
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select purchase request", $this->db);
                exit;
            }

            $query = $query . " ORDER BY PurchaseRequestDirectNumber DESC
                                LIMIT {$numberLimit} OFFSET {$numberOffset}";
            $exec = $this->db->query($query, []);

            if ($exec) {
                $rows = $exec->result_array();
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select purchase request", $this->db);
                exit;
            }

            $result = array(
                "total" => $totalPage,
                "totalFilter" => $totalCount,
                "records" => $rows,
                "sql" => $this->db->last_query()
            );

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

    function searchDetail()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
                exit;
            }

            $payload = $this->sys_input;

            $queryCount = "SELECT count(*) as total
                           FROM purchase_request_direct_detail
                           WHERE PurchaseRequestDirectDetailIsActive = 'Y' 
                           AND PurchaseRequestDirectDetailPurchaseRequestDirectID = {$payload['PRID']}";
            $exec = $this->db->query($queryCount, []);

            $totalCount = 0;

            if ($exec) {
                $totalCount = $exec->result_array()[0]["total"];
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select purchase request detail", $this->db);;
                exit;
            }

            $query = "SELECT *, 
                    ItemUnitID,
                    ItemUnitName,
                    PurchaseDirectCategoryCode,
                    PurchaseDirectCategoryName,
                    ROW_NUMBER() OVER(ORDER BY PurchaseRequestDirectDetailID) RowNumber,
                    '' as isAttachemnt,
                    '' as dataAttachment
                FROM purchase_request_direct_detail 
                JOIN purchase_direct_category ON PurchaseDirectCategoryID = PurchaseRequestDirectDetailPurchaseRequestDirectCategoryID
                LEFT JOIN itemunit ON PurchaseRequestDirectDetailItemUnitID = ItemUnitID
                WHERE PurchaseRequestDirectDetailIsActive = 'Y' 
                AND PurchaseRequestDirectDetailPurchaseRequestDirectID = {$payload['PRID']}
                ORDER BY PurchaseRequestDirectDetailStatus ASC, PurchaseRequestDirectDetailID ASC";
            $exec = $this->db->query($query, []);

            if ($exec) {
                $rows = $exec->result_array();
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select purchase request detail", $this->db);
                exit;
            }

            foreach ($rows as $key => $value) {
                if ($value['PurchaseDirectCategoryName'] !== "BBM") {
                    $rows[$key]['PurchaseRequestDirectDetailAmount'] = intval($value['PurchaseRequestDirectDetailAmount']);
                    $rows[$key]['PurchaseRequestDirectDetailAmountRequest'] = intval($value['PurchaseRequestDirectDetailAmountRequest']);
                    $rows[$key]['PurchaseRequestDirectDetailEstimationPrice'] = intval($value['PurchaseRequestDirectDetailEstimationPrice']);
                    $rows[$key]['PurchaseRequestDirectDetailRealitationPrice'] = intval($value['PurchaseRequestDirectDetailRealitationPrice']);
                    $rows[$key]['PurchaseRequestDirectDetailTotalEstimationPrice'] = intval($value['PurchaseRequestDirectDetailTotalEstimationPrice']);
                    $rows[$key]['PurchaseRequestDirectDetailTotalRealitationPrice'] = intval($value['PurchaseRequestDirectDetailTotalRealitationPrice']);
                }

                $sql = "SELECT PurchaseDirectAttachmentID,
                            PurchaseDirectAttachmentPurchaseRequestDirectDetailID,
                            PurchaseDirectAttachmentName
                            FROM purchase_direct_attachment
                            WHERE PurchaseDirectAttachmentIsActive = 'Y'
                            AND PurchaseDirectAttachmentPurchaseRequestDirectDetailID = ?";
                $qry = $this->db->query($sql, [$value['PurchaseRequestDirectDetailID']]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("select purchase_direct_attachment", $this->db);
                    exit;
                }
                // echo $this->db->last_query();
                // exit;

                $rowsdata = $qry->result_array();

                if (count($rowsdata) > 0) {
                    $rows[$key]['isAttachemnt'] = true;
                    $rows[$key]['dataAttachment'] = $rowsdata;
                } else {
                    $rows[$key]['isAttachemnt'] = false;
                    $rows[$key]['dataAttachment'] = [];
                }
            }

            $result = array(
                "totalFilter" => $totalCount,
                "records" => $rows,
                "sql" => $this->db->last_query()
            );

            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }
    function getlevel()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }

            $payload = $this->sys_input;
            $user = $this->sys_user;
            $regionalID = $user['S_RegionalID'];
            $branchCode = $user['M_BranchCode'];
            $loginType = $user['M_UserLocationFlag'];
            $userID = $user['M_UserID'];
            $sql = "SELECT m_approve_level.* FROM m_user
                JOIN m_approve_level
                ON M_UserM_ApproveLevelID = M_ApproveLevelID
                WHERE M_UserID = ?";
            $qry = $this->db->query($sql, [$userID]);
            if (!$qry) {
                $this->sys_error_db("Error cek approval level");
                exit;
            }
            $approvalLevel = $qry->result_array();
            if (count($approvalLevel) == 0) {
                $result = array(
                    'total' => 0,
                    'records' => []
                );
                $this->sys_ok($result);
                exit;
            } else {
                $result = array(
                    "total" => 1,
                    "records" => $approvalLevel,
                    "sql" => $this->db->last_query()
                );

                $this->sys_ok($result);
            }
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }
    function deleteDetail()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }

            $payload = $this->sys_input;
            $userId = $this->sys_user["M_UserID"];

            $sqlDetail = "UPDATE purchase_request_direct_detail SET
                          PurchaseRequestDirectDetailIsActive = 'N',
                          PurchaseRequestDirectDetailDeleted = NOW(),
                          PurchaseRequestDirectDetailDeletedUserID = {$userId}
                          WHERE PurchaseRequestDirectDetailStatus = 'Pending'
                          AND PurchaseRequestDirectDetailID = {$payload['PRDID']}
                          AND PurchaseRequestDirectDetailIsActive = 'Y'";
            $exec = $this->db->query($sqlDetail, []);
            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("reject request error", $this->db);
                exit;
            } else {
                $sqlTotalPrice = "SELECT SUM(PurchaseRequestDirectDetailTotalEstimationPrice) AS Total
                                  FROM purchase_request_direct_detail
                                  WHERE PurchaseRequestDirectDetailPurchaseRequestDirectID = {$payload['PRID']}
                                  AND PurchaseRequestDirectDetailIsActive = 'Y'";
                $exec = $this->db->query($sqlTotalPrice, []);
                $total = 0;

                if (!$exec) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("order purchase request error", $this->db);
                    exit;
                } else {
                    $total = $exec->result_array()[0]["Total"] ?? 0;
                }

                $sql = "UPDATE purchase_request_direct SET
                        PurchaseRequestDirectTotalEstimation = {$total},
                        PurchaseRequestDirectTotalRealitation = {$total},
                        PurchaseRequestLastUpdated = NOW(),
                        PurchaseRequestLastUpdatedUserID = {$userId}
                        WHERE PurchaseRequestDirectID = {$payload['PRID']}
                        AND PurchaseRequestDirectIsActive = 'Y'";
                $exec = $this->db->query($sql, []);
                $this->db->trans_commit();
                $result = array("total" => 1, "records" => array("xPRDID" => $payload['PRDID']));
                $this->sys_ok($result);
            }
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function approveRequest()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }

            $payload = $this->sys_input;
            $userId = $this->sys_user["M_UserID"];

            $sqlDetail = "UPDATE purchase_request_direct_detail SET
                          PurchaseRequestDirectDetailStatus = 'Ordered',
                          PurchaseRequestDirectDetailLastUpdated = NOW(),
                          PurchaseRequestDirectDetailLastUpdatedUserID = {$userId}
                          WHERE PurchaseRequestDirectDetailStatus = 'Pending'
                          AND PurchaseRequestDirectDetailPurchaseRequestDirectID = {$payload['PRID']}
                          AND PurchaseRequestDirectDetailIsActive = 'Y'";
            $exec = $this->db->query($sqlDetail, []);
            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("approve request error", $this->db);
                exit;
            }

            $total = 0;
            $query = "SELECT SUM(IF(PurchaseRequestDirectDetailTotalRealitationPrice IS NULL, PurchaseRequestDirectDetailTotalEstimationPrice,PurchaseRequestDirectDetailTotalRealitationPrice)) as total
                      FROM purchase_request_direct_detail
                      WHERE PurchaseRequestDirectDetailIsActive = 'Y'
                      AND PurchaseRequestDirectDetailPurchaseRequestDirectID = {$payload['PRID']}";
            $exec = $this->db->query($query);
            if ($exec) {
                $total = $exec->row()->total;
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select purchase_request_direct_detail", $this->db);
                exit;
            }

            $sql = "UPDATE purchase_request_direct SET
                    PurchaseRequestDirectNote = '{$payload['PRNote']}',
                    PurchaseRequestDirectStatus = 'Approved',
                    PurchaseRequestDirectApprovedDate = NOW(),
                    PurchaseRequestDirectApprovedBy = {$userId},
                    PurchaseRequestDirectTotalRealitation = {$total},
                    PurchaseRequestLastUpdated = NOW(),
                    PurchaseRequestLastUpdatedUserID = {$userId}
                    WHERE PurchaseRequestDirectStatus = 'Pending'
                    AND PurchaseRequestDirectID = {$payload['PRID']}
                    AND PurchaseRequestDirectIsActive = 'Y'";
            $exec = $this->db->query($sql, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("approve request error", $this->db);
                exit;
            }

            $rowQuery = "SELECT prd.*,
                         mu.M_UserFullName AS M_RequesterFullName
                         FROM purchase_request_direct AS prd
                         INNER JOIN m_user AS mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                         WHERE PurchaseRequestDirectID = {$payload['PRID']}
                         AND PurchaseRequestDirectIsActive = 'Y'";
            $exec = $this->db->query($rowQuery, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("approve request error", $this->db);
                exit;
            }
            $datas_log = array();
            $sql = "SELECT * FROM purchase_request_direct WHERE PurchaseRequestDirectID = ? AND PurchaseRequestDirectIsActive = 'Y'";
            $query = $this->db->query($sql, [$payload['PRID']]);
            if (!$query) {
                $this->db->trans_rollback();
                $this->sys_error_db("purchase request select", $this->db);
                exit;
            }
            $header = $query->row_array();


            $datas_log['header'] = $header;
            $sql = "SELECT * 
                    FROM purchase_request_direct_detail 
                    JOIN itemunit ON PurchaseRequestDirectDetailItemUnitID = ItemUnitID
                    WHERE PurchaseRequestDirectDetailPurchaseRequestDirectID = ? AND PurchaseRequestDirectDetailIsActive = 'Y'";
            $query = $this->db->query($sql, [$payload['PRID']]);
            if (!$query) {
                $this->db->trans_rollback();
                $this->sys_error_db("purchase request detail select", $this->db);
                exit;
            }
            $details = $query->result_array();
            $datas_log['details'] = $details;

            $rowQuery = "SELECT prd.*,
                         mu.M_UserFullName AS M_RequesterFullName
                         FROM purchase_request_direct AS prd
                         INNER JOIN m_user AS mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                         WHERE PurchaseRequestDirectID = {$payload['PRID']}
                         AND PurchaseRequestDirectIsActive = 'Y'";
            $exec = $this->db->query($rowQuery, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("approve request error", $this->db);
                exit;
            }

            // Notification
            $this->readNotif("A", $userId, $payload['PRID']);

            $messages = "Purchase Request Direct dengan kode " . $header['PurchaseRequestDirectNumber'] . " telah di approved";
            $this->insert_act_log("PRD", "Approved", $messages, $payload['PRID'], $this->safeJsonEncode($datas_log), $userId);
            $this->db->trans_commit();
            $result = array("total" => 1, "records" => $exec->result_array());
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function rejectRequest()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }

            $payload = $this->sys_input;
            $userId = $this->sys_user["M_UserID"];

            $sql = "UPDATE purchase_request_direct SET
                    PurchaseRequestDirectStatus = 'Draft',
                    PurchaseRequestLastUpdated = NOW(),
                    PurchaseRequestLastUpdatedUserID = {$userId}
                    WHERE PurchaseRequestDirectStatus = 'Pending'
                    AND PurchaseRequestDirectID = {$payload["PRID"]}
                    AND PurchaseRequestDirectIsActive = 'Y'";
            $exec = $this->db->query($sql, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("reject request error", $this->db);
                exit;
            }
            $datas_log = array();
            $sql = "SELECT * FROM purchase_request_direct WHERE PurchaseRequestDirectID = ? AND PurchaseRequestDirectIsActive = 'Y'";
            $query = $this->db->query($sql, [$payload['PRID']]);
            if (!$query) {
                $this->db->trans_rollback();
                $this->sys_error_db("purchase request select", $this->db);
                exit;
            }
            $header = $query->row_array();


            $datas_log['header'] = $header;
            $sql = "SELECT * 
                    FROM purchase_request_direct_detail 
                    JOIN itemunit ON PurchaseRequestDirectDetailItemUnitID = ItemUnitID
                    WHERE PurchaseRequestDirectDetailPurchaseRequestDirectID = ? AND PurchaseRequestDirectDetailIsActive = 'Y'";
            $query = $this->db->query($sql, [$payload['PRID']]);
            if (!$query) {
                $this->db->trans_rollback();
                $this->sys_error_db("purchase request detail select", $this->db);
                exit;
            }
            $details = $query->result_array();
            $datas_log['details'] = $details;

            $rowQuery = "SELECT prd.*,
                         mu.M_UserFullName AS M_RequesterFullName
                         FROM purchase_request_direct AS prd
                         INNER JOIN m_user AS mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                         WHERE PurchaseRequestDirectID = {$payload['PRID']}
                         AND PurchaseRequestDirectIsActive = 'Y'";
            $exec = $this->db->query($rowQuery, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("approve request error", $this->db);
                exit;
            }

            // Notification
            $this->readNotif("R", $userId, $payload['PRID']);

            $messages = "Purchase Request Direct dengan kode " . $header['PurchaseRequestDirectNumber'] . " telah di reject";
            $this->insert_act_log("PRD", "Reject", $messages, $payload['PRID'], $this->safeJsonEncode($datas_log), $userId);
            $this->db->trans_commit();
            $result = array("total" => 1, "records" => array("xPRID" => $payload["PRID"]));
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function unApproveRequest()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }

            $payload = $this->sys_input;
            $userId = $this->sys_user["M_UserID"];

            $sql = "UPDATE purchase_request_direct SET
                    PurchaseRequestDirectStatus = 'Pending',
                    PurchaseRequestLastUpdated = NOW(),
                    PurchaseRequestLastUpdatedUserID = {$userId}
                    WHERE PurchaseRequestDirectStatus = 'Approved'
                    AND PurchaseRequestDirectID = {$payload["PRID"]}
                    AND PurchaseRequestDirectIsActive = 'Y'";
            $exec = $this->db->query($sql, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("unapprove request error", $this->db);
                exit;
            }
            $datas_log = array();
            $sql = "SELECT * FROM purchase_request_direct WHERE PurchaseRequestDirectID = ? AND PurchaseRequestDirectIsActive = 'Y'";
            $query = $this->db->query($sql, [$payload['PRID']]);
            if (!$query) {
                $this->db->trans_rollback();
                $this->sys_error_db("purchase request select", $this->db);
                exit;
            }
            $header = $query->row_array();


            $datas_log['header'] = $header;
            $sql = "SELECT * 
                    FROM purchase_request_direct_detail 
                    JOIN itemunit ON PurchaseRequestDirectDetailItemUnitID = ItemUnitID
                    WHERE PurchaseRequestDirectDetailPurchaseRequestDirectID = ? AND PurchaseRequestDirectDetailIsActive = 'Y'";
            $query = $this->db->query($sql, [$payload['PRID']]);
            if (!$query) {
                $this->db->trans_rollback();
                $this->sys_error_db("purchase request detail select", $this->db);
                exit;
            }
            $details = $query->result_array();
            $datas_log['details'] = $details;

            $rowQuery = "SELECT prd.*,
                         mu.M_UserFullName AS M_RequesterFullName
                         FROM purchase_request_direct AS prd
                         INNER JOIN m_user AS mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                         WHERE PurchaseRequestDirectID = {$payload['PRID']}
                         AND PurchaseRequestDirectIsActive = 'Y'";
            $exec = $this->db->query($rowQuery, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("approve request error", $this->db);
                exit;
            }

            // Notification
            $this->readNotif("U", $userId, $payload['PRID']);

            $messages = "Purchase Request Direct dengan kode " . $header['PurchaseRequestDirectNumber'] . " telah di unappprove";
            $this->insert_act_log("PRD", "Unapprove", $messages, $payload['PRID'], $this->safeJsonEncode($datas_log), $userId);
            $this->db->trans_commit();
            $result = array("total" => 1, "records" => array("xPRID" => $payload["PRID"]));
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function updateDetail()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }

            $payload = $this->sys_input;
            $userId = $this->sys_user["M_UserID"];
            /* $price = 0;

            $sqlPrice = "SELECT PurchaseRequestDirectDetailEstimationPrice AS Price
                         FROM purchase_request_direct_detail
                         WHERE PurchaseRequestDirectDetailID = {$payload['PRDID']}";
            $exec = $this->db->query($sqlPrice, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("update amount error", $this->db);
                exit;
            } else {
                $price = $exec->result_array()[0]["Price"];
            }
            */

            // $PRDTotal = $payload['PRDAmount'] * $payload['PRDPrice'];
            $PRDTotal = $payload['PRDTotal'];

            $sqlDetail = "UPDATE purchase_request_direct_detail SET
                          PurchaseRequestDirectDetailAmount = {$payload['PRDAmount']},
                          PurchaseRequestDirectDetailRealitationPrice = {$payload['PRDPrice']},
                          PurchaseRequestDirectDetailTotalRealitationPrice = {$PRDTotal},
                          PurchaseRequestDirectDetailLastUpdated = NOW(),
                          PurchaseRequestDirectDetailLastUpdatedUserID = {$userId}
                          WHERE PurchaseRequestDirectDetailID = {$payload['PRDID']}
                          AND PurchaseRequestDirectDetailIsActive = 'Y'";
            $exec = $this->db->query($sqlDetail, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("update amount error", $this->db);
                exit;
            }

            $total = 0;
            $query = "SELECT SUM(IF(PurchaseRequestDirectDetailTotalRealitationPrice IS NULL, PurchaseRequestDirectDetailTotalEstimationPrice,PurchaseRequestDirectDetailTotalRealitationPrice)) as total
                      FROM purchase_request_direct_detail
                      WHERE PurchaseRequestDirectDetailIsActive = 'Y'
                      AND PurchaseRequestDirectDetailPurchaseRequestDirectID = {$payload['PRID']}";
            $exec = $this->db->query($query);
            if ($exec) {
                $total = $exec->row()->total;
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select purchase_request_direct_detail", $this->db);
                exit;
            }

            $sql = "UPDATE purchase_request_direct SET
                    PurchaseRequestDirectTotalRealitation = {$total},
                    PurchaseRequestLastUpdated = NOW(),
                    PurchaseRequestLastUpdatedUserID = {$userId}
                    WHERE  PurchaseRequestDirectID = {$payload['PRID']}";
            $exec = $this->db->query($sql, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("purchase_request_direct request error", $this->db);
                exit;
            }

            $this->db->trans_commit();
            $result = array("total" => 1, "records" => array("PRDID" => $payload['PRDID']));
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }
    private function safeJsonEncode($data)
    {
        // Coba encode data ke JSON
        $jsonData = json_encode($data);

        // Cek apakah terjadi error saat encode
        if (json_last_error() !== JSON_ERROR_NONE) {
            $errorMsg = json_last_error_msg();
            error_log("JSON encode error: " . $errorMsg);

            // Lakukan sanitasi dan perbaikan data
            $fixedData = $this->fixJsonEncodeIssues($data, $errorMsg);

            // Coba encode lagi setelah diperbaiki
            $jsonData = json_encode($fixedData);

            // Jika masih error, log dan kembalikan objek kosong
            if (json_last_error() !== JSON_ERROR_NONE) {
                error_log("Failed to fix JSON encode issues: " . json_last_error_msg());
                // Kembalikan objek kosong jika masih gagal
                return '{}';
            }
        }

        return $jsonData;
    }

    // Fungsi untuk memperbaiki masalah encoding JSON
    private function fixJsonEncodeIssues($data, $errorMsg)
    {
        // Buat salinan data untuk dimodifikasi
        $fixedData = $data;

        // Tangani berbagai jenis error
        if (strpos($errorMsg, 'Malformed UTF-8') !== false) {
            // Perbaiki masalah karakter UTF-8
            $fixedData = $this->fixUTF8Issues($fixedData);
        } else if (strpos($errorMsg, 'Inf and NaN cannot be JSON encoded') !== false) {
            // Perbaiki masalah nilai Infinity atau NaN
            $fixedData = $this->fixInfNanIssues($fixedData);
        } else {
            // Konversi semua nilai numerik menjadi string untuk menghindari masalah presisi
            $fixedData = $this->convertNumericValuesToStrings($fixedData);

            // Perbaiki masalah referensi recursif
            $fixedData = $this->fixRecursiveReferences($fixedData);
        }

        return $fixedData;
    }

    // Perbaiki masalah karakter UTF-8
    private function fixUTF8Issues($data)
    {
        if (is_string($data)) {
            return mb_convert_encoding($data, 'UTF-8', 'UTF-8');
        } else if (is_array($data)) {
            foreach ($data as $key => $value) {
                $data[$key] = $this->fixUTF8Issues($value);
            }
        }
        return $data;
    }

    // Perbaiki masalah nilai Infinity atau NaN
    private function fixInfNanIssues($data)
    {
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                if (is_float($value) && (is_nan($value) || is_infinite($value))) {
                    $data[$key] = (string)$value; // Konversi ke string
                } else if (is_array($value)) {
                    $data[$key] = $this->fixInfNanIssues($value);
                }
            }
        }
        return $data;
    }

    // Perbaiki masalah referensi recursif
    private function fixRecursiveReferences($data, $depth = 0)
    {
        // Batasi kedalaman rekursi untuk menghindari infinite loop
        if ($depth > 50) {
            return "[MAX_DEPTH_REACHED]";
        }

        if (is_array($data)) {
            $result = [];
            foreach ($data as $key => $value) {
                if (is_array($value)) {
                    $result[$key] = $this->fixRecursiveReferences($value, $depth + 1);
                } else {
                    $result[$key] = $value;
                }
            }
            return $result;
        }

        return $data;
    }

    // Cari dan konversi numerik ke string secara rekursif
    private function convertNumericValuesToStrings($data)
    {
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                if (is_array($value)) {
                    $data[$key] = $this->convertNumericValuesToStrings($value);
                } else if (is_numeric($value)) {
                    $data[$key] = (string)$value;
                } else if (is_bool($value)) {
                    $data[$key] = $value ? "true" : "false";
                }
            }
        }
        return $data;
    }

    function insert_act_log($code, $status, $description, $refId, $data, $userId)
    {
        $sql = "INSERT INTO user_activity(
                                UserActivityCode,
                                UserActivityStatus,
                                UserActivityDescription,
                                UserActivityRefID,
                                UserActivityData,
                                UserActivityUserID,
                                UserActivityCreated) 
                    VALUES (?,?,?,?,?,?,?)";
        $query = $this->db->query($sql, [$code, $status, $description, $refId, $data, $userId, date("Y-m-d H:i:s")]);
        if (!$query) {
            $this->sys_error_db("user activity", $this->db);
            exit;
        }
    }

    // read notification
    function readNotif($type, $userId, $refID)
    {

        $this->db->trans_begin();

        // cari user penerima notifikasi
        if ($type == "U") {
            $sql_get = "SELECT PurchaseRequestDirectID,
                M_UserID,
                M_UserUsername,
                NotificationID,
                NotificationDetailID,
                NotificationDetailStatus,
                NotificationDetailM_UserID,
                NotificationDetailM_ApproveLevelID
                FROM purchase_request_direct  
                JOIN notification ON NotificationRefID = PurchaseRequestDirectID
                JOIN notification_detail ON NotificationID = NotificationDetailNotificationID
                AND NotificationDetailStatus = 'read'
                JOIN m_user ON NotificationUserID = M_UserID
                    AND M_UserIsActive = 'Y'
                WHERE PurchaseRequestDirectID = ?
                AND PurchaseRequestDirectIsActive = 'Y'";
            $qry = $this->db->query($sql_get, [$refID]);
            if (!$qry) {
                $this->sys_error_db("select user notification error", $this->db);
                exit;
            }
            $rowsuser = $qry->result_array();
        } else {
            $sql_get = "SELECT PurchaseRequestDirectID,
                M_UserID,
                M_UserUsername,
                NotificationID,
                NotificationDetailID,
                NotificationDetailStatus,
                NotificationDetailM_UserID,
                NotificationDetailM_ApproveLevelID
                FROM purchase_request_direct  
                JOIN notification ON NotificationRefID = PurchaseRequestDirectID
                JOIN notification_detail ON NotificationID = NotificationDetailNotificationID
                AND NotificationDetailStatus = 'unread'
                JOIN m_user ON NotificationUserID = M_UserID
                    AND M_UserIsActive = 'Y'
                WHERE PurchaseRequestDirectID = ?
                AND PurchaseRequestDirectIsActive = 'Y'";
            $qry = $this->db->query($sql_get, [$refID]);
            if (!$qry) {
                $this->sys_error_db("select user notification error", $this->db);
                exit;
            }
            $rowsuser = $qry->result_array();
        }


        foreach ($rowsuser as $user) {

            if ($type == "A") {
                // verifikasi manager
                $sql = "UPDATE notification_detail SET 
                        NotificationDetailStatus = 'read',
                        NotificationDetailLastUpdated = NOW(),
                        NotificationDetailUserID = ?
                        WHERE NotificationDetailNotificationID = ?";
                $qry = $this->db->query($sql, [$userId, $user["NotificationID"]]);
                if (!$qry) {
                    $this->sys_error_db("update notification error", $this->db);
                    exit;
                }
            } else if ($type == "R") {
                $sql = "UPDATE notification_detail SET 
                        NotificationDetailStatus = 'read',
                        NotificationDetailLastUpdated = NOW(),
                        NotificationDetailUserID = ?
                        WHERE NotificationDetailNotificationID = ?";
                $qry = $this->db->query($sql, [$userId, $user["NotificationID"]]);
                if (!$qry) {
                    $this->sys_error_db("update notification error", $this->db);
                    exit;
                }
            } else if ($type == "U") {
                $sql = "UPDATE notification_detail SET 
                        NotificationDetailStatus = 'unread',
                        NotificationDetailLastUpdated = NOW(),
                        NotificationDetailUserID = ?
                        WHERE NotificationDetailNotificationID = ?";
                $qry = $this->db->query($sql, [$userId, $user["NotificationID"]]);
                if (!$qry) {
                    $this->sys_error_db("update notification error", $this->db);
                    exit;
                }
            }
        }

        $this->db->trans_commit();
    }
}
