<?php

class PurchaseRequestDirectRealitation extends MY_Controller
{
    var $db;

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

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

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

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

            $startdate = $payload["startdate"];
            $enddate = $payload["enddate"];

            $query = "SELECT pv.*,
                M_BranchID,
                M_BranchCode,
                M_BranchName,
                CONCAT(cs.coaAccountNo, ' | ', cs.coaDescription) as CoaSource,
                -- CONCAT(ce.coaAccountNo, ' | ', ce.coaDescription) as CoaExpense,
                CONCAT(ct.coaAccountNo, ' | ', ct.coaDescription) as CoaTemporary,
                ur.M_UserFullName as user_realitation,
                up.M_UserFullName as user_paid,
                prd.PurchaseRequestDirectDescription as requestDirectDescription,
                uprd.M_UserUsername as user_request,
                prd.PurchaseRequestDirectID as requestDirectID,
                '' as dataAttachment,
                '' as requestNumber                
            FROM payment_voucher as pv
            JOIN payment_voucher_detail pvd ON pv.PaymentVoucherID = pvd.PaymentVoucherDetailPaymentVoucherID
            AND pvd.PaymentVoucherDetailIsActive = 'Y'
            LEFT JOIN purchase_request_direct prd ON pvd.PaymentVoucherDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
            AND prd.PurchaseRequestDirectIsActive = 'Y'
            LEFT JOIN m_user uprd ON uprd.M_UserID = prd.PurchaseRequestCreatedUserID
            LEFT JOIN m_user ur ON ur.M_UserID = PaymentVoucherRealitationUserID
            LEFT JOIN m_user up ON up.M_UserID = PaymentVoucherPaidUserID
            LEFT JOIN m_branch ON M_BranchCode = PaymentVoucherM_BranchCode
            JOIN coa cs ON cs.coaID = PaymentVoucherCoaSourceID
            JOIN coa ct ON ct.coaID = PaymentVoucherCoaTemporaryID
            -- JOIN coa ce ON ce.coaID = PaymentVoucherCoaExpenseID
            WHERE PaymentVoucherIsActive = 'Y'
            AND DATE(PaymentVoucherDate) BETWEEN '{$startdate}' AND '{$enddate}'
            AND (PaymentVoucherNumber LIKE '%" . $payload["search"] . "%')";
                      
            $queryCount = "SELECT count(*) as total
            FROM payment_voucher as pv
            JOIN payment_voucher_detail pvd ON pv.PaymentVoucherID = pvd.PaymentVoucherDetailPaymentVoucherID
            AND pvd.PaymentVoucherDetailIsActive = 'Y'
            LEFT JOIN purchase_request_direct prd ON pvd.PaymentVoucherDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
            AND prd.PurchaseRequestDirectIsActive = 'Y'
            LEFT JOIN m_user uprd ON uprd.M_UserID = prd.PurchaseRequestCreatedUserID
            WHERE PaymentVoucherIsActive = 'Y' 
            AND DATE(PaymentVoucherDate) BETWEEN '{$startdate}' AND '{$enddate}'
            AND (PaymentVoucherNumber LIKE '%" . $payload["search"] . "%')";

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

            $exec = $this->db->query($queryCount, []);
            // echo $this->db->last_query();
            // exit;

            $numberLimit = 20;
            $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 payment voucher", $this->db);;
                exit;
            }

            $query .= " GROUP BY PaymentVoucherID 
                        ORDER BY PaymentVoucherRealitationDate 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 payment voucher", $this->db);
                exit;
            }

            foreach ($rows as $key => $value) {
                // ambil attachment dari purchase request direct detail
                $sql = "SELECT
                        PurchaseDirectAttachmentID,
                        PurchaseDirectAttachmentName
                        FROM purchase_direct_attachment 
                        JOIN purchase_request_direct_detail ON PurchaseRequestDirectDetailID = PurchaseDirectAttachmentPurchaseRequestDirectDetailID
                        AND PurchaseRequestDirectDetailIsActive = 'Y'
                        AND PurchaseRequestDirectDetailPurchaseRequestDirectID = ?
                        WHERE PurchaseDirectAttachmentIsActive = 'Y'";
                $qry = $this->db->query($sql, [$value['requestDirectID']]);
                if (!$qry) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("select purchase_request_direct_detail", $this->db);
                    exit;
                }

                $rowsdata = $qry->result_array();

                // ambil attachment dari payment voucher paid attach
                $sqlp = "SELECT PaymentVoucherPaidAttachID,
                        PaymentVoucherPaidAttachName as PurchaseDirectAttachmentName
                        FROM payment_voucher_paid_attach
                        WHERE PaymentVoucherPaidAttachIsActive = 'Y'
                        AND PaymentVoucherPaidAttachPaymentVoucherID = ?";
                $qryp = $this->db->query($sqlp, [$value['PaymentVoucherID']]);
                if (!$qryp) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("select purchase_request_direct_detail", $this->db);
                    exit;
                }

                $rowsdatap = $qryp->result_array();

                $arrMerges = array_merge($rowsdata, $rowsdatap);

                $rows[$key]['dataAttachment'] = $arrMerges;

                // get request number
                $sqlreq = "SELECT
                      PurchaseRequestDirectID,
                      PurchaseRequestDirectNumber,
                      PurchaseRequestDirectDescription
                      FROM payment_voucher_detail 
                      LEFT JOIN purchase_request_direct ON PurchaseRequestDirectID = PaymentVoucherDetailPurchaseRequestDirectID
                      AND PurchaseRequestDirectIsActive = 'Y'
                      WHERE PaymentVoucherDetailIsActive = 'Y' 
                      AND PaymentVoucherDetailPaymentVoucherID = ?";
                $qrysql = $this->db->query($sqlreq, [$value['PaymentVoucherID']]);
                if (!$qrysql) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("select purchase_request_direct error", $this->db);
                    exit;
                }

                $rowsnumber = $qrysql->result_array();
                $rows[$key]['requestNumber'] = $rowsnumber;
            }

            $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 payment_voucher_detail
                           WHERE PaymentVoucherDetailIsActive = 'Y' 
                           AND PaymentVoucherDetailPaymentVoucherID = {$payload['ID']}";
            $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 payment voucher detail", $this->db);;
                exit;
            }

            $query = "SELECT payment_voucher_detail.*, 
                ROW_NUMBER() OVER(ORDER BY PaymentVoucherDetailID) RowNumber,
                PurchaseRequestDirectID,
                PurchaseRequestDirectNumber,
                PurchaseRequestDirectAdjustment,
                PurchaseRequestDirectNotaStatus,
                PurchaseRequestDirectNotaApprovedBy,
                SUM(IFNULL(PurchaseRequestDirectDetailTotalRealitationPrice, 0)) as realised_price,
                GROUP_CONCAT(
                    IFNULL(CONCAT(PurchaseRequestDirectDetailAccount, ' | ', coaDescription), 'notset') 
                    SEPARATOR '; '
                ) AS account_biaya,
                M_UserUsername
            FROM payment_voucher_detail 
            JOIN purchase_request_direct ON PurchaseRequestDirectID = PaymentVoucherDetailPurchaseRequestDirectID
            JOIN purchase_request_direct_detail ON PurchaseRequestDirectDetailPurchaseRequestDirectID = PurchaseRequestDirectID
                AND PurchaseRequestDirectDetailIsActive = 'Y'
            LEFT JOIN coa ON coaAccountNo = PurchaseRequestDirectDetailAccount 
                AND coaIsActive = 'Y'
            LEFT JOIN m_user ON PurchaseRequestCreatedUserID = M_UserID
                AND PurchaseRequestDirectIsActive = 'Y'
            WHERE PaymentVoucherDetailIsActive = 'Y' 
                AND PaymentVoucherDetailPaymentVoucherID = {$payload['ID']}
            GROUP BY PurchaseRequestDirectNumber, PaymentVoucherDetailID, PurchaseRequestDirectID";
            $exec = $this->db->query($query, []);

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

            $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 getBranch()
    {
        try {
            $payload = $this->sys_input;
            $query = "SELECT DISTINCT
                      M_BranchCode,
                      M_BranchName
                      FROM m_branch
                      WHERE M_BranchIsActive = 'Y'
                      AND (M_BranchCode LIKE '%" . $payload["search"] . "%' OR M_BranchName LIKE '%" . $payload["search"] . "%')
                      ORDER BY M_BranchName ASC";
            $exec = $this->db->query($query, []);
            if ($exec) {
                $rows = $exec->result_array();
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select branch", $this->db);
                exit;
            }

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

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

    function getCoa()
    {
        try {
            $payload = $this->sys_input;
            $query = "SELECT * FROM coa
                      WHERE coaIsActive = 'Y' AND coaIsInput = 'Y'
                      AND (coaAccountNo LIKE '%" . $payload["search"] . "%' OR coaDescription LIKE '%" . $payload["search"] . "%')
                      ORDER BY coaAccountNo ASC";
            $exec = $this->db->query($query, []);
            if ($exec) {
                $rows = $exec->result_array();
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select coa", $this->db);
                exit;
            }

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

            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }
    function getPurchase()
    {
        try {
            $payload = $this->sys_input;
            $query = "SELECT *
                      FROM purchase_request_direct
                      WHERE PurchaseRequestDirectIsActive = 'Y'
                      AND PurchaseRequestDirectApprovedBy IS NOT NULL
                      AND PurchaseRequestDirectM_BranchCode = '{$payload["branchcode"]}'
                      AND PurchaseRequestDirectID not in ( 
            select PaymentVoucherDetailPurchaseRequestDirectID from payment_voucher
            JOIN payment_voucher_detail ON PaymentVoucherDetailPaymentVoucherID = PaymentVoucherID AND PaymentVoucherDetailIsActive = 'Y'
            where PaymentVoucherIsActive = 'Y')
                      ORDER BY PurchaseRequestDirectNumber ASC";
            $exec = $this->db->query($query, []);
            if ($exec) {
                $rows = $exec->result_array();
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select branch", $this->db);
                exit;
            }

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

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

    function getTotalDraft()
    {
        try {
            $payload = $this->sys_input;
            $total = 0;
            $query = "SELECT COUNT(*) as total
                      FROM payment_voucher
                      WHERE PaymentVoucherIsActive = 'Y'
                      AND PaymentVoucherStatus = 'Draft'";
            $exec = $this->db->query($query);
            if ($exec) {
                $total = $exec->row()->total;
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select branch", $this->db);
                exit;
            }

            $result = array(
                "total" => $total,
                "sql" => $this->db->last_query()
            );

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

    function getTotalPaid()
    {
        try {
            $payload = $this->sys_input;
            $total = 0;
            $query = "SELECT COUNT(*) as total
                      FROM payment_voucher
                      WHERE PaymentVoucherIsActive = 'Y'
                      AND PaymentVoucherStatus = 'Paid'";
            $exec = $this->db->query($query);
            if ($exec) {
                $total = $exec->row()->total;
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select branch", $this->db);
                exit;
            }

            $result = array(
                "total" => $total,
                "sql" => $this->db->last_query()
            );

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

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

            $payload = $this->sys_input;

            $sql = "SELECT 
                PurchaseRequestDirectID,
                PurchaseRequestDirectNumber,
                prdd.PurchaseRequestDirectDetailID as detail_id,
                prdd.PurchaseRequestDirectDescription,
                IFNULL(PurchaseRequestDirectDetailTotalEstimationPrice, 0) AS estimate_price,
                IFNULL(PurchaseRequestDirectDetailTotalRealitationPrice, 0) AS realised_price,
                PurchaseRequestDirectAdjustment, 
                PurchaseDirectCategoryName
            FROM payment_voucher_detail 
            JOIN purchase_request_direct ON PurchaseRequestDirectID = PaymentVoucherDetailPurchaseRequestDirectID
            JOIN purchase_request_direct_detail prdd ON PurchaseRequestDirectDetailPurchaseRequestDirectID = PurchaseRequestDirectID 
                AND PurchaseRequestDirectDetailIsActive = 'Y'
            JOIN purchase_direct_category ON PurchaseDirectCategoryID = PurchaseRequestDirectDetailPurchaseRequestDirectCategoryID
            WHERE PaymentVoucherDetailIsActive = 'Y' 
                AND PaymentVoucherDetailPaymentVoucherID = ?";
            $que = $this->db->query($sql, [$payload['ID']]);
            if (!$que) {
                $this->sys_error_db("[Error] get voucher detail");
                exit;
            }
            $data = $que->result_array();

            foreach ($data as $key => $value) {
                $sql_nota = "SELECT 
                    PurchaseDirectAttachmentID as nota_id,
                    PurchaseDirectAttachmentPurchaseRequestDirectDetailID,
                    PurchaseDirectAttachmentName as img_url
                FROM purchase_direct_attachment
                WHERE PurchaseDirectAttachmentIsActive = 'Y'
                    AND PurchaseDirectAttachmentPurchaseRequestDirectDetailID = ?";
                $que_nota = $this->db->query($sql_nota, [$value['detail_id']]);
                if (!$que_nota) {
                    $this->sys_error_db("[Error] get voucher detail");
                    exit;
                }
                $nota = $que_nota->result_array();

                $data[$key]['prevNota'] = $nota;

                // helper placeholder
                $data[$key]['attachPreview'] = [];
                $data[$key]['attachFiles'] = [];

                $data[$key]['realised_price'] = floatval($value['realised_price']);
            }

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

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

            $param = $this->sys_input;
            $this->db->trans_begin();

            foreach ($param['detail'] as $key => $obj) {
                $sql = "UPDATE purchase_request_direct_detail SET 
                    PurchaseRequestDirectDetailTotalRealitationPrice = ? 
                    WHERE PurchaseRequestDirectDetailID = ?";
                $que = $this->db->query($sql, [$obj['realised_price'], $obj['detail_id']]);
                if (!$que) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed to insert realized price item", $this->db);
                    exit;
                }
            }

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

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

            $this->db->trans_begin();

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

            $pdSql = "SELECT `fn_numbering`('PV') AS PV";
            $exec = $this->db->query($pdSql, []);
            $pd = "";
            $dateNow = date('Y-m-d');

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("payment voucher insert error", $this->db);
                exit;
            } else {
                $pd = $exec->result_array()[0]["PV"];
            }

            $sql = "INSERT INTO payment_voucher(
                    PaymentVoucherDate,
                    PaymentVoucherNumber,
                    PaymentVoucherM_BranchCode,	
                    PaymentVoucherCoaSourceID,	
                    PaymentVoucherCoaExpenseID,	
                    PaymentVoucherCoaTemporaryID,
                    PaymentVoucherTotal,
                    PaymentVoucherStatus,
                    PaymentVoucherUserID,	
                    PaymentVoucherCreated,	
                    PaymentVoucherLastUpdated)
                     VALUES ('{$dateNow}', 
                     '{$pd}', 
                     '{$payload['BranchCode']}', 
                     '{$payload['CoaSourceID']}',
                     '{$payload['CoaExpenseID']}',
                     '{$payload['CoaTemporaryID']}',
                     '{$payload['total']}',
                     'Draft',
                     {$userId}, 
                     now(),
                     now())";
            $exec = $this->db->query($sql);
            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("payment voucher insert error", $this->db);
                exit;
            }

            $last_id = $this->db->insert_id();
            foreach ($payload['details'] as $k => $v) {
                $sql = "INSERT INTO payment_voucher_detail(
                    PaymentVoucherDetailPaymentVoucherID,	
                    PaymentVoucherDetailPurchaseRequestDirectID,	
                    PaymentVoucherDetailTotal,	
                    PaymentVoucherDetailUserID,	
                    PaymentVoucherDetailCreated,	
                    PaymentVoucherDetailLastUpdated)
                     VALUES ('{$last_id}', 
                     '{$v['PurchaseRequestDirectID']}', 
                     '{$v['PurchaseRequestDirectTotalRealitation']}',
                     {$userId}, 
                     now(),
                     now())";
                $exec = $this->db->query($sql);
                if (!$exec) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("payment voucher detail insert error", $this->db);
                    exit;
                }
            }
            $this->db->trans_commit();

            $newInsert = "SELECT * FROM payment_voucher WHERE PaymentVoucherNumber = '{$pd}' AND PaymentVoucherIsActive = 'Y'";
            $records = $this->db->query($newInsert, [])->result_array();

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

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


            $this->db->trans_begin();

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

            $sqlGetReceiver = "SELECT PurchaseRequestCreatedUserID 
                    FROM payment_voucher_detail pvd
                    JOIN purchase_request_direct prd ON prd.PurchaseRequestDirectID = pvd.PaymentVoucherDetailPurchaseRequestDirectID
                    WHERE pvd.PaymentVoucherDetailPaymentVoucherID = ?
                    AND pvd.PaymentVoucherDetailIsActive = 'Y'
                    LIMIT 1";
            $sqlreceive = $this->db->query($sqlGetReceiver, [$payload['ID']]);
            if (!$sqlreceive) {
                $this->sys_error_db("get receiver error", $this->db);
                exit;
            }
            $receiveUserId = $sqlreceive->row()->PurchaseRequestCreatedUserID;

            $sql = "UPDATE payment_voucher SET
                    PaymentVoucherTotalRest = ?,
                    PaymentVoucherRealitationDate = now(), 	
                    PaymentVoucherRealitationNote = ?, 
                    PaymentVoucherRealitationUserID = ?,
                    PaymentVoucherRealitationReceiveUserID = ?,
                    PaymentVoucherStatus = 'Realitation',
                    PaymentVoucherLastUpdated = now()
                    WHERE PaymentVoucherID = ?";
            $exec = $this->db->query($sql, [
                $payload['restPrice'],
                $payload['note'],
                $userId,
                $receiveUserId,
                $payload['ID']
            ]);

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


            $sqlData = "SELECT payment_voucher.*,
                M_BranchID,
                M_BranchCode,
                M_BranchName,
                M_BranchS_RegionalID,
                M_BranchCompanyID,
                M_BranchCompanyName,
                CONCAT('Jurnal PV Realisasi Kasir ', DATE_FORMAT(now(), '%d-%m-%Y')) xdescription,
                0 periodeid,
                CONCAT('Jurnal PV Realisasi Kasir ', DATE_FORMAT(now(), '%d-%m-%Y'), ' cabang ',M_BranchName) title,
                14 typeid,
                '' detailjurnal,
                cs.coaDescription as CoaSource,
                ce.coaDescription as CoaExpense,
                ct.coaDescription as CoaTemporary,
                PaymentVoucherTotalRest,
                ABS(PaymentVoucherTotal - IFNULL(PaymentVoucherTotalRest,0)) as ExpenseTotal
            FROM payment_voucher 
            JOIN m_branch ON M_BranchCode = PaymentVoucherM_BranchCode
            LEFT JOIN m_branch_companydetail ON M_BranchCompanyDetailM_BranchCode = M_BranchCode AND M_BranchCompanyDetailIsActive = 'Y'
            LEFT JOIN m_branch_company ON M_BranchCompanyID = M_BranchCompanyDetailM_BranchCompanyID AND M_BranchCompanyIsActive = 'Y'
            JOIN coa cs ON cs.coaID = PaymentVoucherCoaSourceID
            JOIN coa ce ON ce.coaID = PaymentVoucherCoaExpenseID
            JOIN coa ct ON ct.coaID = PaymentVoucherCoaTemporaryID
            WHERE PaymentVoucherID = {$payload['ID']} AND PaymentVoucherIsActive = 'Y'";
            $newData = $this->db->query($sqlData)->result_array();

            if ($newData) {
                foreach ($newData as $k => $v) {

                    $sqlDesc = "SELECT prdd.PurchaseRequestDirectDetailID,
                                prdd.PurchaseRequestDirectDescription, 
                                prdd.PurchaseRequestDirectDetailAmountRequest,
                                prd.PurchaseRequestCreatedUserID
                                FROM purchase_request_direct_detail prdd
                                JOIN purchase_request_direct prd ON prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                                AND prd.PurchaseRequestDirectIsActive = 'Y'
                                JOIN payment_voucher_detail pvd ON  pvd.PaymentVoucherDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                                AND pvd.PaymentVoucherDetailIsActive = 'Y'
                                AND pvd.PaymentVoucherDetailPaymentVoucherID = ?
                                WHERE prdd.PurchaseRequestDirectDetailIsActive = 'Y'";
                    $qryDesc = $this->db->query($sqlDesc, [$v['PaymentVoucherID']]);
                    if (!$qryDesc) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("purchase_request_direct_detail get error", $this->db);
                        exit;
                    }
                    $rowsdesc = $qryDesc->result_array();

                    // Ambil nama user request
                    $sqlUser = "SELECT M_UserUsername FROM m_user WHERE M_UserIsActive = 'Y' AND M_UserID = ?";
                    $qryUser = $this->db->query($sqlUser, [$rowsdesc[0]['PurchaseRequestCreatedUserID']]);
                    if ($qryUser) {
                        $userRequestName = $qryUser->row()->M_UserUsername;
                    } else {
                        $this->sys_error_db("m_user get error", $this->db);
                        exit;
                    }

                    // Ambil semua deskripsi
                    $descList = array_map(function ($item) {
                        return $item['PurchaseRequestDirectDescription'];
                    }, $rowsdesc);

                    // Gabungkan dengan koma
                    $descJoined = implode(', ', $descList);

                    $description = rtrim($v["xdescription"], ".") . "." . " Nama user request: " . $userRequestName . " Keterangan: " . $descJoined;

                    $periodeid = 0;
                    $branchid = $v["M_BranchID"];
                    $branchcompanyid = $v["M_BranchCompanyID"];
                    $date = date('Y-m-d');
                    $regionalid = $v["M_BranchS_RegionalID"];
                    $title = $v["title"];
                    $typeid = $v["typeid"];
                    $pvno = $v["PaymentVoucherNumber"];

                    $sqlperiode = "SELECT periodeID FROM periode WHERE '{$date}' BETWEEN periodeStartDate AND periodeEndDate";
                    $periodeid = $this->db->query($sqlperiode)->row()->periodeID;

                    $sqluser = "SELECT prd.PurchaseRequestDirectID,
                            M_UserUsername 
                            FROM purchase_request_direct prd
                            JOIN payment_voucher_detail pvd ON  pvd.PaymentVoucherDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                            AND pvd.PaymentVoucherDetailIsActive = 'Y'
                            AND pvd.PaymentVoucherDetailPaymentVoucherID = ?
                            LEFT JOIN m_user mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                            WHERE prd.PurchaseRequestDirectIsActive = 'Y'";
                    $qryuser = $this->db->query($sqluser, [$v['PaymentVoucherID']]);
                    if (!$qryuser) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("purchase_request_direct get error", $this->db);
                        exit;
                    }

                    $rowuser = $qryuser->result_array()[0]['M_UserUsername'];

                    if (isset($payload['restPrice'])) {

                        if (intval($payload['restPrice']) > intval($v["PaymentVoucherTotal"])) {
                            $detailjurnal = [
                                [
                                    'coaid' => $v["PaymentVoucherCoaTemporaryID"],
                                    'xdescription' => $v["CoaTemporary"] . ' (' . $rowuser . ')',
                                    'debit' => 0,
                                    'credit' => $v["PaymentVoucherTotal"]
                                ],
                                [
                                    'coaid' => $v["PaymentVoucherCoaExpenseID"],
                                    'xdescription' => $v["CoaExpense"],
                                    'debit' => $payload['restPrice'],
                                    'credit' => 0
                                ],
                                [
                                    'coaid' => $v["PaymentVoucherCoaSourceID"],
                                    'xdescription' => $v["CoaSource"],
                                    'debit' => 0,
                                    'credit' => $v["ExpenseTotal"]
                                ]
                            ];
                        } else {
                            $detailjurnal = [
                                [
                                    'coaid' => $v["PaymentVoucherCoaSourceID"],
                                    'xdescription' => $v["CoaSource"],
                                    'debit' => $v["ExpenseTotal"],
                                    'credit' => 0
                                ],
                                [
                                    'coaid' => $v["PaymentVoucherCoaExpenseID"],
                                    'xdescription' => $v["CoaExpense"],
                                    'debit' => $payload['restPrice'],
                                    'credit' => 0
                                ],
                                [
                                    'coaid' => $v["PaymentVoucherCoaTemporaryID"],
                                    'xdescription' => $v["CoaTemporary"] . ' (' . $rowuser . ')',
                                    'debit' => 0,
                                    'credit' => $v["PaymentVoucherTotal"]
                                ]
                            ];
                        }
                    } else {
                        $detailjurnal = [
                            [
                                'coaid' => $v["PaymentVoucherCoaExpenseID"],
                                'xdescription' => $v["CoaExpense"],
                                'debit' => $v["PaymentVoucherTotal"],
                                'credit' => 0
                            ],
                            [
                                'coaid' => $v["PaymentVoucherCoaTemporaryID"],
                                'xdescription' => $v["CoaTemporary"] . ' (' . $rowuser . ')',
                                'debit' => 0,
                                'credit' => $v["PaymentVoucherTotal"]
                            ]
                        ];
                    }

                    $this->savejurnalrealitation($branchid, $date, $description, $periodeid, $regionalid, $title, $typeid, $detailjurnal, $pvno, $branchcompanyid);
                }
            }

            $sql = "UPDATE payment_voucher_detail SET 
                    PaymentVoucherDetailIsRealitation = 'Y' 
                    WHERE PaymentVoucherDetailPaymentVoucherID = {$payload['ID']}";
            $exec = $this->db->query($sql, []);

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

            if (!$this->uploadRealitationImage($payload['ID'], $userId)) {
                return; // kalau gagal, hentikan proses
            }

            $this->db->trans_commit();

            $newUpdate = "SELECT * FROM payment_voucher WHERE PaymentVoucherID = {$payload['ID']} AND PaymentVoucherIsActive = 'Y'";
            $records = $this->db->query($newUpdate, [])->result_array();

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

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

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

            $sqlReceiver = "SELECT 
                PurchaseRequestCreatedUserID 
            FROM payment_voucher_detail 
            JOIN purchase_request_direct ON PurchaseRequestDirectID = PaymentVoucherDetailPurchaseRequestDirectID 
            WHERE PaymentVoucherDetailIsActive = 'Y'
                AND PaymentVoucherDetailPaymentVoucherID = ?
            LIMIT 1";
            $queReceiver = $this->db->query($sqlReceiver, [$payload['ID']]);
            if (!$queReceiver) {
                $this->db->trans_rollback();
                $this->sys_error_db("get receiver error", $this->db);
                exit;
            }
            $receiveUserId = $queReceiver->row()->PurchaseRequestCreatedUserID;

            $sqlupd = "UPDATE payment_voucher SET
                PaymentVoucherTotalRest = ?,
                PaymentVoucherRealitationDate = now(), 	
                PaymentVoucherRealitationNote = ?, 
                PaymentVoucherRealitationUserID = ?,
                PaymentVoucherRealitationReceiveUserID = ?,
                PaymentVoucherStatus = 'Realitation',
                PaymentVoucherLastUpdated = now()
            WHERE PaymentVoucherID = ?";
            $queupd = $this->db->query($sqlupd, [
                $payload['restPrice'], $payload['note'],
                $userid, $receiveUserId, $payload['ID']
            ]);
            if (!$queupd) {
                $this->db->trans_rollback();
                $this->sys_error_db("payment voucher update error", $this->db);
                exit;
            }

            $items = json_decode($payload['data'], true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                $this->sys_error("[Error] invalid json data");
                exit;
            }

            foreach ($items as $key => $item) {
                $sql = "UPDATE purchase_request_direct_detail SET 
                    PurchaseRequestDirectDetailTotalRealitationPrice = ? 
                    WHERE PurchaseRequestDirectDetailID = ?";
                $que = $this->db->query($sql, [$item['realised_price'], $item['detail_id']]);
                if (!$que) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] failed to insert realized price item");
                    exit;
                }
            }

            $sqldata = "SELECT payment_voucher.*,
                M_BranchID,
                M_BranchCode,
                M_BranchName,
                M_BranchS_RegionalID,
                M_BranchCompanyID,
                M_BranchCompanyName,
                CONCAT('Jurnal PV Realisasi Kasir ', DATE_FORMAT(now(), '%d-%m-%Y')) xdescription,
                0 periodeid,
                CONCAT('Jurnal PV Realisasi Kasir ', DATE_FORMAT(now(), '%d-%m-%Y'), ' cabang ',M_BranchName) title,
                14 typeid,
                '' detailjurnal,
                cs.coaDescription as CoaSource,
                ct.coaDescription as CoaTemporary,
                PaymentVoucherTotalRest,
                ABS(PaymentVoucherTotal - IFNULL(PaymentVoucherTotalRest,0)) as ExpenseTotal
            FROM payment_voucher 
            JOIN m_branch ON M_BranchCode = PaymentVoucherM_BranchCode
            LEFT JOIN m_branch_companydetail ON M_BranchCompanyDetailM_BranchCode = M_BranchCode AND M_BranchCompanyDetailIsActive = 'Y'
            LEFT JOIN m_branch_company ON M_BranchCompanyID = M_BranchCompanyDetailM_BranchCompanyID AND M_BranchCompanyIsActive = 'Y'
            JOIN coa cs ON cs.coaID = PaymentVoucherCoaSourceID
            JOIN coa ct ON ct.coaID = PaymentVoucherCoaTemporaryID
            WHERE PaymentVoucherID = ? 
                AND PaymentVoucherIsActive = 'Y'";
            $quedata = $this->db->query($sqldata, [$payload['ID']]);
            if (!$quedata) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get data payment voucher", $this->db);
                exit;
            }
            $newData = $quedata->result_array();
            if ($newData) {
                foreach ($newData as $key => $obj) {
                    $sqldesc = "SELECT 
                        prdd.PurchaseRequestDirectDetailID,
                        prdd.PurchaseRequestDirectDescription, 
                        prdd.PurchaseRequestDirectDetailAmountRequest,
                        prd.PurchaseRequestCreatedUserID,
                        IFNULL(PurchaseRequestDirectDetailTotalRealitationPrice, 0) AS realised_price,
                        PurchaseRequestDirectDetailAccount AS realised_accNo,
                        ca.coaID AS realised_accID,
                        ca.coaDescription AS realised_accDesc,
                        prd.PurchaseRequestDirectAdjustment AS adjust_price,
                        prd.PurchaseRequestDirectAdjustmentAccount AS adjust_accNo,
                        cb.coaID AS adjust_accID,
                        cb.coaDescription AS adjust_accDesc,
                        M_UserUserName as adjust_userBy
                    FROM purchase_request_direct_detail prdd
                    JOIN purchase_request_direct prd ON prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                        AND prd.PurchaseRequestDirectIsActive = 'Y'
                    JOIN coa ca ON ca.coaAccountNo = PurchaseRequestDirectDetailAccount 
                        AND ca.coaIsActive = 'Y'
                    LEFT JOIN coa cb ON cb.coaAccountNo = prd.PurchaseRequestDirectAdjustmentAccount
                        AND cb.coaIsActive = 'Y'
                    JOIN m_user ON M_UserID = PurchaseRequestLastUpdatedUserID
                    JOIN payment_voucher_detail pvd ON  pvd.PaymentVoucherDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                        AND pvd.PaymentVoucherDetailIsActive = 'Y'
                        AND pvd.PaymentVoucherDetailPaymentVoucherID = ?
                    WHERE prdd.PurchaseRequestDirectDetailIsActive = 'Y'";
                    $quedesc = $this->db->query($sqldesc, [$obj['PaymentVoucherID']]);
                    if (!$quedesc) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("purchase_request_direct_detail get error", $this->db);
                        exit;
                    }
                    $newdesc = $quedesc->result_array();

                    $sqluser = "SELECT M_UserUsername FROM m_user WHERE M_UserIsActive = 'Y' AND M_UserID = ?";
                    $queuser = $this->db->query($sqluser, [$newdesc[0]['PurchaseRequestCreatedUserID']]);
                    if (!$queuser) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("m_user get error", $this->db);
                        exit;
                    }
                    $userRequestName = $queuser->row()->M_UserUsername;

                    $desclist = array_map(function($item) {
                        return $item['PurchaseRequestDirectDescription'];
                    }, $newdesc);
                    $descjoin = implode(', ', $desclist);
                    $description = rtrim($obj["xdescription"], ".") . "." . " Nama user request: " . $userRequestName . " Keterangan: " . $descjoin;

                    $periodeid = 0;
                    $branchid = $obj["M_BranchID"];
                    $branchcompanyid = $obj["M_BranchCompanyID"];
                    $date = date('Y-m-d');
                    $regionalid = $obj["M_BranchS_RegionalID"];
                    $title = $obj["title"];
                    $typeid = $obj["typeid"];
                    $pvno = $obj["PaymentVoucherNumber"];

                    $sqlperiode = "SELECT periodeID FROM periode WHERE '{$date}' BETWEEN periodeStartDate AND periodeEndDate";
                    $queperiode = $this->db->query($sqlperiode, []);
                    if (!$queperiode) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] get perioder jurnal", $this->db);
                        exit;
                    }
                    $periodeid = $queperiode->row()->periodeID;
                    if (intval($periodeid) == 0) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] periode jurnal tidak ditemukan", $this->db);
                        exit;
                    }

                    $sqluserAcctemp = "SELECT prd.PurchaseRequestDirectID,
                        M_UserUsername 
                    FROM purchase_request_direct prd
                    JOIN payment_voucher_detail pvd ON  pvd.PaymentVoucherDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                        AND pvd.PaymentVoucherDetailIsActive = 'Y'
                        AND pvd.PaymentVoucherDetailPaymentVoucherID = ?
                    LEFT JOIN m_user mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                    WHERE prd.PurchaseRequestDirectIsActive = 'Y'";
                    $queuserAcctemp = $this->db->query($sqluserAcctemp, [$obj['PaymentVoucherID']]);
                    if (!$queuserAcctemp) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("purchase_request_direct get error", $this->db);
                        exit;
                    }
                    $userAcctemp = $queuserAcctemp->result_array()[0]['M_UserUsername'];

                    $detailjurnal = [];
                    if (isset($payload['restPrice'])) {
                        if (intval($payload['restPrice']) > intval($obj["PaymentVoucherTotal"])) {
                            foreach ($newdesc as $key => $val) {
                                $temp = [
                                    'coaid' => $val['realised_accID'],
                                    'xdescription' => $val["realised_accDesc"],
                                    'debit' => $val["realised_price"],
                                    'credit' => 0
                                ];
                                $detailjurnal[] = $temp;
                            }

                            $detailjurnal[] = [
                                'coaid' => $obj["PaymentVoucherCoaTemporaryID"],
                                'xdescription' => $obj["CoaTemporary"] . ' (' . $userAcctemp . ')',
                                'debit' => 0,
                                'credit' => $obj["PaymentVoucherTotal"]
                            ];

                            // jika ada tambahan harga/uang sebelum realisasi oleh kacab
                            if ($newdesc[0]['adjust_accNo'] != '') {
                                $adjustedby = $newdesc[0]['adjust_userBy'];
                                $detailjurnal[] = [
                                    'coaid' => $newdesc[0]['adjust_accID'],
                                    'xdescription' => $newdesc[0]['adjust_accDesc'] . " ($adjustedby) ",
                                    'debit' => 0,
                                    'credit' => $newdesc[0]['adjust_price']
                                ];
                            } else {
                                $detailjurnal[] = [
                                    'coaid' => $obj["PaymentVoucherCoaSourceID"],
                                    'xdescription' => $obj["CoaSource"],
                                    'debit' => 0,
                                    'credit' => $obj["ExpenseTotal"]
                                ];
                            }
                        } else {
                            foreach ($newdesc as $key => $val) {
                                $temp = [
                                    'coaid' => $val['realised_accID'],
                                    'xdescription' => $val["realised_accDesc"],
                                    'debit' => $val["realised_price"],
                                    'credit' => 0
                                ];
                                $detailjurnal[] = $temp;
                            }

                            $detailjurnal[] = [
                                'coaid' => $obj["PaymentVoucherCoaSourceID"],
                                'xdescription' => $obj["CoaSource"],
                                'debit' => $obj["ExpenseTotal"],
                                'credit' => 0
                            ];
                            $detailjurnal[] = [
                                'coaid' => $obj["PaymentVoucherCoaTemporaryID"],
                                'xdescription' => $obj["CoaTemporary"] . ' (' . $userAcctemp . ')',
                                'debit' => 0,
                                'credit' => $obj["PaymentVoucherTotal"]
                            ];
                        }
                    } else {
                        foreach ($newdesc as $key => $val) {
                            $temp = [
                                'coaid' => $val['realised_accID'],
                                'xdescription' => $val["realised_accDesc"],
                                'debit' => $val["realised_price"],
                                'credit' => 0
                            ];
                            $detailjurnal[] = $temp;
                        }
                        $detailjurnal[] = [
                            'coaid' => $obj["PaymentVoucherCoaTemporaryID"],
                            'xdescription' => $obj["CoaTemporary"] . ' (' . $userAcctemp . ')',
                            'debit' => 0,
                            'credit' => $obj["PaymentVoucherTotal"]
                        ];
                    }

                    $this->savejurnalrealitation($branchid, $date, $description, $periodeid, $regionalid, $title, $typeid, $detailjurnal, $pvno, $branchcompanyid);

                }
            }

            $sql = "UPDATE payment_voucher_detail SET 
                    PaymentVoucherDetailIsRealitation = 'Y' 
                    WHERE PaymentVoucherDetailPaymentVoucherID = {$payload['ID']}";
            $exec = $this->db->query($sql, []);
            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("payment voucher detail update error", $this->db);
                exit;
            }

            if (isset($_FILES['files'])) {
                if (!$this->uploadRealitationImageV2($payload['ID'], $userid)) {
                    return; // kalau gagal, hentikan proses
                }   
            }

            $this->db->trans_commit();
            $newUpdate = "SELECT * FROM payment_voucher WHERE PaymentVoucherID = {$payload['ID']} AND PaymentVoucherIsActive = 'Y'";
            $records = $this->db->query($newUpdate, [])->result_array();

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

    private function uploadRealitationImage($paymentVoucherID, $userId)
    {
        $path = "/home/one/project/accone/one-media/cashier/";
        $config['upload_path'] = $path;
        $config['allowed_types'] = 'jpg|jpeg|png';
        $config['max_size'] = '10000';
        $count = count($_FILES['files']['name']);
        $this->load->library('upload', $config);

        // ambil nomor payment voucher
        $sql = "SELECT PaymentVoucherNumber FROM payment_voucher WHERE PaymentVoucherID = ?";
        $qry = $this->db->query($sql, [$paymentVoucherID]);
        if (!$qry) {
            $this->sys_error_db("select PaymentVoucherNumber", $this->db);
            exit;
        }
        $numberpaymnet = $qry->row()->PaymentVoucherNumber;

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

                $ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
                $new_filename = "P" . date("YmdHis") . "_" . $numberpaymnet . "." . $ext;

                $config['file_name'] = $new_filename;
                $this->upload->initialize($config);

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

                    // simpan ke DB
                    $sqlUpdate = "INSERT INTO payment_voucher_realitation_attach(
                                    PaymentVoucherRealitationAttachPaymentVoucherID,
                                    PaymentVoucherRealitationAttachName,
                                    PaymentVoucherRealitationAttachCreated,
                                    PaymentVoucherRealitationAttachUserID) VALUES(?,?,NOW(),?)";
                    $res = $this->db->query($sqlUpdate, [$paymentVoucherID, $filename, $userId]);
                    if (!$res) {
                        $this->sys_error_db("update payment_voucher_realitation_attach error", $this->db);
                        exit;
                    }
                } else {
                    $error = $this->upload->display_errors();
                    $this->sys_error("Upload gagal: " . $error);
                    exit;
                }
            }
        }
        return true;
    }

    private function uploadRealitationImageV2($paymentVoucherID, $userId) {
        if (!isset($_POST['data']) || !isset($_FILES['files'])) {
            $this->db->trans_rollback();
            $this->sys_error("[Error] files or data missing");
            exit;
        }

        $items = json_decode($_POST['data'], true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->db->trans_rollback();
            $this->sys_error("[Error] invalid json data");
            exit;
        }

        $path = "/home/one/project/accone/one-media/cashier/";
        $config['upload_path'] = $path;
        $config['allowed_types'] = 'jpg|jpeg|png';
        $config['max_size'] = '10000';
        $this->load->library('upload', $config);

        $sql = "SELECT PaymentVoucherNumber FROM payment_voucher WHERE PaymentVoucherID = ?";
        $que = $this->db->query($sql, [$paymentVoucherID]);
        if (!$que) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] get PaymentVoucherNumber");
            exit;
        }
        // $numberpaymnet = $que->row()->PaymentVoucherNumber;
        $numberpaymnet = $que->row_array()['PaymentVoucherNumber'];

        $fileIndex = 0;
        foreach ($items as $key => $item) {
            if (isset($item['fileCount']) && $item['fileCount'] > 0) {
                for ($i=0; $i < $item['fileCount']; $i++) { 
                    if (!empty($_FILES['files']['name'][$fileIndex])) {
                        $_FILES['file']['name']     = $_FILES['files']['name'][$fileIndex];
                        $_FILES['file']['type']     = $_FILES['files']['type'][$fileIndex];
                        $_FILES['file']['tmp_name'] = $_FILES['files']['tmp_name'][$fileIndex];
                        $_FILES['file']['error']    = $_FILES['files']['error'][$fileIndex];
                        $_FILES['file']['size']     = $_FILES['files']['size'][$fileIndex];

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

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

                            $sql_update = "INSERT INTO payment_voucher_realitation_attach (
                                PaymentVoucherRealitationAttachPaymentVoucherID,
                                PaymentVoucherRealitationAttachPurchaseRequestDirectDetailID,
                                PaymentVoucherRealitationAttachName,
                                PaymentVoucherRealitationAttachCreated,
                                PaymentVoucherRealitationAttachUserID
                            ) VALUES (?,?,?,NOW(),?)";
                            $que_update = $this->db->query($sql_update, [
                                $paymentVoucherID, $item['detail_id'], $filename, $userId
                            ]);
                            if (!$que_update) {
                                $this->db->trans_rollback();
                                $this->sys_error_db("[Error] insert attachment files");
                                exit;
                            }
                        } else {
                            $error = $this->upload->display_errors();
                            $this->db->trans_rollback();
                            $this->sys_error("Upload gagal: " . $error);
                            exit;
                        }
                    }
                    $fileIndex++;
                }
            }
        }
        return true;
    }

    function savejurnalrealitation($branchid, $date, $description, $periodeid, $regionalid, $title, $typeid, $detailjurnal, $pvno, $branchcompanyid)
    {
        try {
            if (! $this->isLogin) {
                $this->sys_error("Invalid Token");
                exit;
            }

            $this->db->trans_begin();
            $userid = $this->sys_user['M_UserID'];

            $sql_branch = "SELECT 
                    M_BranchID,
                    M_BranchCode,
                    M_BranchName
                    FROM m_branch
                    WHERE M_BranchIsActive = 'Y'
                    AND M_BranchID = ?";
            $qry_branch = $this->db->query($sql_branch, array($branchid));
            if ($qry_branch) {
                $branchcodex = $qry_branch->row()->M_BranchCode;
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select branch error", $this->db);
                exit;
            }

            $sql = "INSERT INTO jurnal(
                    jurnalM_BranchCompanyID,
                    JurnalS_RegionalID,
                    jurnalM_BranchCode,
                    jurnalperiodeID,
                    jurnalNo,
                    jurnalTitle,
                    jurnalDescription,
                    jurnalDate,
                    jurnalJurnalTypeID,
                    jurnalIsActive,
                    jurnalCreated,
                    jurnalM_UserID
                    ) VALUES(?,?,?,?,`fn_numbering`('J'),?,?,?,?,'Y',NOW(),?)";
            $qry = $this->db->query($sql, array(
                $branchcompanyid,
                $regionalid,
                $branchcodex,
                $periodeid,
                $title,
                $description,
                $date,
                $typeid,
                $userid
            ));
            $last_qry = $this->db->last_query();
            if (!$qry) {
                $this->db->trans_rollback();
                $error = array(
                    "message" => $this->db->error()["message"],
                    "sql" => $last_qry
                );
                $this->sys_error_db($error, $this->db);
                exit;
            }

            $last_id = $this->db->insert_id();

            foreach ($detailjurnal as $key => $value) {
                $sql_detail = "INSERT INTO jurnal_tx(
                                jurnalTxJurnalID,
                                jurnalTxCoaID,
                                jurnalTxDescription,
                                jurnalTxDebit,
                                jurnalTxCredit,
                                jurnalTxIsActive,
                                jurnalTxCreated,
                                jurnalTxM_UserID) VALUES(?,?,?,?,?,'Y',NOW(),?)";
                $qry_detail = $this->db->query($sql_detail, array(
                    $last_id,
                    $value["coaid"],
                    $value["xdescription"],
                    $value["debit"],
                    $value["credit"],
                    $userid
                ));
                $last_qry = $this->db->last_query();
                if (!$qry_detail) {
                    $this->db->trans_rollback();
                    $error = array(
                        "message" => $this->db->error()["message"],
                        "sql" => $last_qry
                    );
                    $this->sys_error_db($error, $this->db);
                    exit;
                }

                $tx_id = $this->db->insert_id();

                $sql = "INSERT INTO jurnal_addon 
                (jurnalAddOnJurnalID, 
                jurnalAddOnJurnalTxID, 
                jurnalAddOnCode, 
                jurnalAddOnValue, 
                jurnalAddOnCreated, 
                jurnalAddOnCreatedUserID, 
                jurnalAddOnLastUpdatedUserID, 
                jurnalAddOnLastUpdated) 
                VALUES
                (?,	
                ?,	
                'PVNO',	
                ?,	
                now(),	
                ?,	
                ?,
                now())";
                $qry = $this->db->query($sql, array(
                    $last_id,
                    $tx_id,
                    $pvno,
                    $userid,
                    $userid
                ));
                $last_qry = $this->db->last_query();
                if (!$qry) {
                    $this->db->trans_rollback();
                    $error = array(
                        "message" => $this->db->error()["message"],
                        "sql" => $last_qry
                    );
                    $this->sys_error_db($error, $this->db);
                    exit;
                }
            }


            $this->db->trans_commit();
            //  $result = array("total" => 1);
            //  $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    public function uploadnew_old($img, $tanggal, $id)
    {

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

        $home_dir = "/home/one/project/accone/";
        $target_dir = $home_dir . "one-media/cashier/";

        $sqlsum = "select PaymentVoucherNumber from payment_voucher
             where PaymentVoucherID = $id";
        $PaymentVoucherNumber = $this->db->query($sqlsum)->row()->PaymentVoucherNumber;

        if (!file_exists($target_dir)) {
            mkdir($target_dir, 0755, true);
        }
        $filename = "R" . date("YmdHis") . "_" . $PaymentVoucherNumber . ".jpg";
        $target_path = $target_dir .  $filename;
        $this->base64_to_jpeg($img, $target_path);
        $sql = "UPDATE payment_voucher SET PaymentVoucherRealitationAttach = '{$filename}'
                                     WHERE PaymentVoucherID = {$id}";
        //echo $sql;
        $save = $this->db->query($sql);

        // $result = array("url" => "http://" . $_SERVER['SERVER_NAME'] . "/one-media/cashier/" . $filename. "?d=" . date("YmdHis"));
        //        $this->sys_ok($result);
        //      exit;
    }

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


            $this->db->trans_begin();

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

            $sql = "UPDATE payment_voucher SET
                    PaymentVoucherPaidDate = now(), 	
                    PaymentVoucherPaidNote = ?, 
                    PaymentVoucherPaidUserID = ?,
                    PaymentVoucherPaidReceiveUserID = ?,
                    PaymentVoucherStatus = 'Paid',
                    PaymentVoucherLastUpdated = now()
                    WHERE PaymentVoucherID = ?";
            $exec = $this->db->query($sql, [
                $payload['note'],
                $userId,
                $payload['userReceiveID'],
                $payload['ID']
            ]);

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

            // if ($payload['img'] !== "") {
            //     $this->uploadpaid($payload['img'], date("YmdHis"), $payload['ID']);
            // }

            $sqlData = "SELECT payment_voucher.*,
             M_BranchID,
             M_BranchCode,
             M_BranchName,
             M_BranchS_RegionalID,
             M_BranchCompanyID,
             M_BranchCompanyName,
             CONCAT('Jurnal PV Pembayaran Kasir ', DATE_FORMAT(now(), '%d-%m-%Y')) xdescription,
             0 periodeid,
             CONCAT('Jurnal PV Pembayaran Kasir ', DATE_FORMAT(now(), '%d-%m-%Y'), ' cabang ',M_BranchName) title,
             14 typeid,
             '' detailjurnal,
             cs.coaDescription as CoaSource,
            ce.coaDescription as CoaExpense,
            ct.coaDescription as CoaTemporary

              FROM payment_voucher 
              JOIN m_branch ON M_BranchCode = PaymentVoucherM_BranchCode
              LEFT JOIN m_branch_companydetail ON M_BranchCompanyDetailM_BranchCode = M_BranchCode AND M_BranchCompanyDetailIsActive = 'Y'
              LEFT JOIN m_branch_company ON M_BranchCompanyID = M_BranchCompanyDetailM_BranchCompanyID AND M_BranchCompanyIsActive = 'Y'
              JOIN coa cs ON cs.coaID = PaymentVoucherCoaSourceID
              JOIN coa ce ON ce.coaID = PaymentVoucherCoaExpenseID
              JOIN coa ct ON ct.coaID = PaymentVoucherCoaTemporaryID
              WHERE PaymentVoucherID = ? AND PaymentVoucherIsActive = 'Y'";
            $sqldata = $this->db->query($sqlData, [$payload['ID']]);
            if ($sqldata) {
                $newData = $sqldata->result_array();
            } else {
                $this->sys_error_db("payment_voucher get error", $this->db);
                exit;
            }
            if ($newData) {
                foreach ($newData as $k => $v) {

                    // ambil desc request
                    $sqlDesc = "SELECT prdd.PurchaseRequestDirectDetailID,
                                prdd.PurchaseRequestDirectDescription, 
                                prdd.PurchaseRequestDirectDetailAmountRequest,
                                prd.PurchaseRequestCreatedUserID
                                FROM purchase_request_direct_detail prdd
                                JOIN purchase_request_direct prd ON prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                                AND prd.PurchaseRequestDirectIsActive = 'Y'
                                JOIN payment_voucher_detail pvd ON  pvd.PaymentVoucherDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                                AND pvd.PaymentVoucherDetailIsActive = 'Y'
                                AND pvd.PaymentVoucherDetailPaymentVoucherID = ?
                                WHERE prdd.PurchaseRequestDirectDetailIsActive = 'Y'";
                    $qryDesc = $this->db->query($sqlDesc, [$v['PaymentVoucherID']]);
                    if (!$qryDesc) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("purchase_request_direct_detail get error", $this->db);
                        exit;
                    }
                    $rowsdesc = $qryDesc->result_array();

                    // Ambil nama user request
                    $sqlUser = "SELECT M_UserUsername FROM m_user WHERE M_UserIsActive = 'Y' AND M_UserID = ?";
                    $qryUser = $this->db->query($sqlUser, [$rowsdesc[0]['PurchaseRequestCreatedUserID']]);
                    if ($qryUser) {
                        $userRequestName = $qryUser->row()->M_UserUsername;
                    } else {
                        $this->sys_error_db("m_user get error", $this->db);
                        exit;
                    }

                    // Ambil semua deskripsi
                    $descList = array_map(function ($item) {
                        return $item['PurchaseRequestDirectDescription'];
                    }, $rowsdesc);

                    // Gabungkan dengan koma
                    $descJoined = implode(', ', $descList);

                    $description = rtrim($v["xdescription"], ".") . "." . " Nama user request: " . $userRequestName . " Keterangan: " . $descJoined;

                    $periodeid = 0;
                    $branchid = $v["M_BranchID"];
                    $branchcompanyid = $v["M_BranchCompanyID"];
                    $date = date('Y-m-d');
                    $regionalid = $v["M_BranchS_RegionalID"];
                    $title = $v["title"];
                    $typeid = $v["typeid"];
                    $pvno = $v["PaymentVoucherNumber"];

                    $sqlperiode = "SELECT periodeID FROM periode WHERE ? BETWEEN periodeStartDate AND periodeEndDate";
                    $sqlperiod = $this->db->query($sqlperiode, [$date]);
                    if (!$sqlperiod) {
                        $this->sys_error_db("periode get error", $this->db);
                        exit;
                    }
                    $periodeid = $sqlperiod->row()->periodeID;

                    $sqluser = "SELECT prd.PurchaseRequestDirectID,
                            M_UserUsername 
                            FROM purchase_request_direct prd
                            JOIN payment_voucher_detail pvd ON  pvd.PaymentVoucherDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
                            AND pvd.PaymentVoucherDetailIsActive = 'Y'
                            AND pvd.PaymentVoucherDetailPaymentVoucherID = ?
                            LEFT JOIN m_user mu ON prd.PurchaseRequestCreatedUserID = mu.M_UserID
                            WHERE prd.PurchaseRequestDirectIsActive = 'Y'";
                    $qryuser = $this->db->query($sqluser, [$v['PaymentVoucherID']]);
                    if (!$qryuser) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("purchase_request_direct get error", $this->db);
                        exit;
                    }

                    $rowuser = $qryuser->result_array()[0]['M_UserUsername'];

                    $detailjurnal = [
                        [
                            'coaid' => $v["PaymentVoucherCoaTemporaryID"],
                            'xdescription' => $v["CoaTemporary"] . ' (' . $rowuser . ')',
                            'debit' => $v["PaymentVoucherTotal"],
                            'credit' => 0
                        ],
                        [
                            'coaid' => $v["PaymentVoucherCoaSourceID"],
                            'xdescription' => $v["CoaSource"],
                            'debit' => 0,
                            'credit' => $v["PaymentVoucherTotal"]
                        ]
                    ];


                    //         $detailjurnal = $this->db->query("SELECT {$v["PaymentVoucherCoaTemporaryID"]} coaid,
                    // '{$v["CoaTemporary"]}' xdescription,
                    // {$v["PaymentVoucherTotal"]} debit,
                    // 0 credit
                    // UNION
                    // SELECT 
                    // {$v["PaymentVoucherCoaSourceID"]} coaid,
                    // '{$v["CoaSource"]}' xdescription,
                    // 0 debit,
                    // {$v["PaymentVoucherTotal"]} credit")->result_array();



                    $this->savejurnalpaid($branchid, $date, $description, $periodeid, $regionalid, $title, $typeid, $detailjurnal, $pvno, $branchcompanyid);
                }
            }



            $sql = "UPDATE payment_voucher_detail SET 
                    PaymentVoucherDetailIsPaid= 'Y' 
                    WHERE PaymentVoucherDetailPaymentVoucherID = ?";
            $exec = $this->db->query($sql, [$payload['ID']]);

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

            if (!$this->uploadPaidImage($payload['ID'], $userId)) {
                return; // kalau gagal, hentikan proses
            }

            $this->db->trans_commit();

            $newUpdate = "SELECT * FROM payment_voucher WHERE PaymentVoucherID = ? AND PaymentVoucherIsActive = 'Y'";
            $sqlrecord = $this->db->query($newUpdate, [$payload['ID']]);
            if (!$sqlrecord) {
                $this->sys_error_db("payment_voucher get error", $this->db);
                exit;
            }
            $records = $sqlrecord->result_array();

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

    private function uploadPaidImage($paymentVoucherID, $userId)
    {
        $path = "/home/one/project/accone/one-media/cashier/";
        $config['upload_path'] = $path;
        $config['allowed_types'] = 'jpg|jpeg|png';
        $config['max_size'] = '10000';
        $count = count($_FILES['files']['name']);
        $this->load->library('upload', $config);

        // ambil nomor payment voucher
        $sql = "SELECT PaymentVoucherNumber FROM payment_voucher WHERE PaymentVoucherID = ?";
        $qry = $this->db->query($sql, [$paymentVoucherID]);
        if (!$qry) {
            $this->sys_error_db("select PaymentVoucherNumber", $this->db);
            exit;
        }
        $numberpaymnet = $qry->row()->PaymentVoucherNumber;

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

                $ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
                $new_filename = "P" . date("YmdHis") . "_" . $numberpaymnet . "." . $ext;

                $config['file_name'] = $new_filename;
                $this->upload->initialize($config);

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

                    // simpan ke DB
                    $sqlUpdate = "INSERT INTO payment_voucher_paid_attach(
                            PaymentVoucherPaidAttachPaymentVoucherID,
                            PaymentVoucherPaidAttachName,
                            PaymentVoucherPaidAttachCreated,
                            PaymentVoucherPaidAttachUserID) VALUES(?,?,NOW(),?)";
                    $res = $this->db->query($sqlUpdate, [$paymentVoucherID, $filename, $userId]);
                    if (!$res) {
                        $this->sys_error_db("update PaymentVoucherPaidAttach error", $this->db);
                        exit;
                    }
                } else {
                    $error = $this->upload->display_errors();
                    $this->sys_error("Upload gagal: " . $error);
                    exit;
                }
            }
        }
        return true;
    }

    function savejurnalpaid($branchid, $date, $description, $periodeid, $regionalid, $title, $typeid, $detailjurnal, $pvno, $branchcompanyid)
    {
        try {
            if (! $this->isLogin) {
                $this->sys_error("Invalid Token");
                exit;
            }

            $this->db->trans_begin();
            $userid = $this->sys_user['M_UserID'];

            $sql_branch = "SELECT 
                    M_BranchID,
                    M_BranchCode,
                    M_BranchName
                    FROM m_branch
                    WHERE M_BranchIsActive = 'Y'
                    AND M_BranchID = ?";
            $qry_branch = $this->db->query($sql_branch, array($branchid));
            if ($qry_branch) {
                $branchcodex = $qry_branch->row()->M_BranchCode;
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select branch error", $this->db);
                exit;
            }

            $sql = "INSERT INTO jurnal(
                    jurnalM_BranchCompanyID,
                    JurnalS_RegionalID,
                    jurnalM_BranchCode,
                    jurnalperiodeID,
                    jurnalNo,
                    jurnalTitle,
                    jurnalDescription,
                    jurnalDate,
                    jurnalJurnalTypeID,
                    jurnalIsActive,
                    jurnalCreated,
                    jurnalM_UserID
                    ) VALUES(?,?,?,?,`fn_numbering`('J'),?,?,?,?,'Y',NOW(),?)";
            $qry = $this->db->query($sql, array(
                $branchcompanyid,
                $regionalid,
                $branchcodex,
                $periodeid,
                $title,
                $description,
                $date,
                $typeid,
                $userid
            ));
            $last_qry = $this->db->last_query();
            if (!$qry) {
                $this->db->trans_rollback();
                $error = array(
                    "message" => $this->db->error()["message"],
                    "sql" => $last_qry
                );
                $this->sys_error_db($error, $this->db);
                exit;
            }

            $last_id = $this->db->insert_id();

            foreach ($detailjurnal as $key => $value) {
                $sql_detail = "INSERT INTO jurnal_tx(
                                jurnalTxJurnalID,
                                jurnalTxCoaID,
                                jurnalTxDescription,
                                jurnalTxDebit,
                                jurnalTxCredit,
                                jurnalTxIsActive,
                                jurnalTxCreated,
                                jurnalTxM_UserID) VALUES(?,?,?,?,?,'Y',NOW(),?)";
                $qry_detail = $this->db->query($sql_detail, array(
                    $last_id,
                    $value["coaid"],
                    $value["xdescription"],
                    $value["debit"],
                    $value["credit"],
                    $userid
                ));
                $last_qry = $this->db->last_query();
                if (!$qry_detail) {
                    $this->db->trans_rollback();
                    $error = array(
                        "message" => $this->db->error()["message"],
                        "sql" => $last_qry
                    );
                    $this->sys_error_db($error, $this->db);
                    exit;
                }

                $tx_id = $this->db->insert_id();

                $sql = "INSERT INTO jurnal_addon 
                (jurnalAddOnJurnalID, 
                jurnalAddOnJurnalTxID, 
                jurnalAddOnCode, 
                jurnalAddOnValue, 
                jurnalAddOnCreated, 
                jurnalAddOnCreatedUserID, 
                jurnalAddOnLastUpdatedUserID, 
                jurnalAddOnLastUpdated) 
                VALUES
                (?,	
                ?,	
                'PVNO',	
                ?,	
                now(),	
                ?,	
                ?,
                now())";
                $qry = $this->db->query($sql, array(
                    $last_id,
                    $tx_id,
                    $pvno,
                    $userid,
                    $userid
                ));
                $last_qry = $this->db->last_query();
                if (!$qry) {
                    $this->db->trans_rollback();
                    $error = array(
                        "message" => $this->db->error()["message"],
                        "sql" => $last_qry
                    );
                    $this->sys_error_db($error, $this->db);
                    exit;
                }
            }


            $this->db->trans_commit();
            //  $result = array("total" => 1);
            //  $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    public function uploadpaid_old($img, $tanggal, $id)
    {

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

        $home_dir = "/home/one/project/accone/";
        $target_dir = $home_dir . "one-media/cashier/";

        $sqlsum = "select PaymentVoucherNumber from payment_voucher
             where PaymentVoucherID = $id";
        $PaymentVoucherNumber = $this->db->query($sqlsum)->row()->PaymentVoucherNumber;

        if (!file_exists($target_dir)) {
            mkdir($target_dir, 0755, true);
        }
        $filename = "P" . date("YmdHis") . "_" . $PaymentVoucherNumber . ".jpg";
        $target_path = $target_dir .  $filename;
        $this->base64_to_jpeg($img, $target_path);
        $sql = "UPDATE payment_voucher SET PaymentVoucherPaidAttach = '{$filename}'
                                     WHERE PaymentVoucherID = {$id}";
        //echo $sql;
        $save = $this->db->query($sql);

        // $result = array("url" => "http://" . $_SERVER['SERVER_NAME'] . "/one-media/cashier/" . $filename. "?d=" . date("YmdHis"));
        //        $this->sys_ok($result);
        //      exit;
    }

    function base64_to_jpeg($base64_string, $output_file)
    {
        // open the output file for writing
        $ifp = fopen($output_file, 'wb');

        // split the string on commas
        // $data[ 0 ] == "data:image/png;base64"
        // $data[ 1 ] == <actual base64 string>
        $data = explode(',', $base64_string);

        // we could add validation here with ensuring count( $data ) > 1
        fwrite($ifp, base64_decode($data[1]));

        // clean up the file resource
        fclose($ifp);

        return $output_file;
    }

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

            */

            $this->db->trans_begin();

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

            $sql = "UPDATE payment_voucher SET
                    PaymentVoucherIsActive = 'N'
                    WHERE PaymentVoucherID = {$payload['ID']}";
            $exec = $this->db->query($sql, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("payment voucher delete error", $this->db);
                exit;
            }
            $sql = "UPDATE payment_voucher_detail SET
                    PaymentVoucherDetailIsActive = 'N'
                    WHERE PaymentVoucherDetailPaymentVoucherID = {$payload['ID']}";
            $exec = $this->db->query($sql, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("payment voucher detail delete error", $this->db);
                exit;
            }
            $this->db->trans_commit();
            $result = array("total" => 1, "records" => array("xId" => 0));
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

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

            $this->db->trans_begin();

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

            $sqlDetail = "UPDATE payment_voucher_detail SET
                          PaymentVoucherDetailLastUpdated = NOW(),
                          PaymentVoucherDetailLastUpdatedUserID = {$userId}
                          WHERE PaymentVoucherDetailPaymentVoucherID = {$payload["ID"]}
                          AND PaymentVoucherDetailIsActive = 'Y'
                          AND PaymentVoucherDetailStatus = 'Pending'";
            $exec = $this->db->query($sqlDetail, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("order payment voucher error", $this->db);
                exit;
            }

            $sql = "UPDATE payment_voucher SET
                PaymentVoucherStatus = 'Pending',
                PurchaseRequestLastUpdated = NOW(),
                PurchaseRequestLastUpdatedUserID = {$userId}
                WHERE PaymentVoucherID = {$payload["ID"]}
                AND PaymentVoucherIsActive = 'Y'";
            $exec = $this->db->query($sql, []);

            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("order payment voucher error", $this->db);
                exit;
            }

            $this->db->trans_commit();

            $sql = "SELECT *, 
                    ROW_NUMBER() OVER(ORDER BY PaymentVoucherNumber) RowNumber 
                    FROM payment_voucher 
                    WHERE PaymentVoucherIsActive = 'Y' 
                    AND PaymentVoucherUserID = {$userId}
                    AND PaymentVoucherID = {$payload["ID"]}";
            $exec = $this->db->query($sql, []);

            $row = [];
            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("order payment voucher error", $this->db);
                exit;
            } else {
                $row = $exec->result_array();
            }
            $result = array("total" => 1, "records" => $row);
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

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

            $prm = $this->sys_input;
            $userId = $prm['userId'];
            $user = $this->sys_user;

            $sql = "SELECT 
                M_UserID,
                M_UserUsername
            FROM m_user
            WHERE M_UserM_BranchID = ?
                AND M_UserS_RegionalID = ?
                AND M_UserIsActive = 'Y'
            ORDER BY M_UserUsername";
            $qry = $this->db->query($sql, [
                $user['M_BranchID'],
                $user['S_RegionalID']
            ]);
            if (!$qry) {
                $this->sys_error_db("get user receive error", $this->db);
                exit;
            }
            $rows = $qry->result_array();
            $result = array(
                "records" => $rows,
                "total" => count($rows)
            );
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function checkPayload() {
        $payload = $this->sys_input;
        $this->sys_ok($payload);
    }
}
