<?php

class PaymentV2 extends MY_Controller
{
    var $db;
    public function index()
    {
        echo "API";
    }

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

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

            $this->db->trans_begin();

            $param = $this->sys_input;
            $users = $this->sys_user;

            # Generate number supplier payment #
            $sql_gennumber = "SELECT `fn_numbering`(?) as numberx";
            $paygroupnum = $this->db->query($sql_gennumber, ['PC'])->row()->numberx;
            $paynumber = $this->db->query($sql_gennumber, ['PN'])->row()->numberx;

            if ($paygroupnum == '' || $paynumber == '') {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] generate number supplier payment");
                exit;
            }

            $rounding = 0;
            if (doubleval($param['xrounding'] > 0)) {
                $sisa = doubleval($param['xrounding']) - doubleval($param['amount']);
                $rounding = round($sisa, 2);
            }

            # UPDATE header supplier payment #
            $sql_updateheader = "UPDATE supplier_payment SET
                SupplierPaymentIsConfirm = 'Y',
                SupplierPaymentConfirmUserID = ?,
                SupplierPaymentGroupNumber = ?,
                SupplierPaymentCashierNumber = ?,
                SupplierPaymentRounding = ?,
                SupplierPaymentConfirmDate = now(),
                SupplierPaymentNote = ?,
    		    SupplierPaymentCoaID = ?
            WHERE SupplierPaymentID = ?";
            $que_updateheader = $this->db->query($sql_updateheader, [
                $users['M_UserID'],
                $paygroupnum,
                $paynumber,
                $rounding,
                $param['keterangan'],
                $param['paymenttype'],
                $param['orderid']
            ]);
            if (!$que_updateheader) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] update supplier payment header");
                exit;
            }

            # UPDATE status lunas supplier invoice #
            $sql_suppinvoice = "UPDATE supplier_invoice
            SET SupplierInvoiceIsLunas = 'Y'
            WHERE SupplierInvoiceID = ?";
            $que_suppinvoice = $this->db->query($sql_suppinvoice, [$param['SupplierInvoiceID']]);
            if (!$que_suppinvoice) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] update status lunas invoice");
                exit;
            }

            # GET Latest data supplier payment #
            $sql_suppayment = "SELECT * FROM supplier_payment WHERE SupplierPaymentID = ?";
            $que_suppayment = $this->db->query($sql_suppayment, [$param['orderid']]);
            if (!$que_suppayment) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get data latest supplier payment");
                exit;
            }
            $suppayment_header = $que_suppayment->row_array();

            $sql_suppaymentdetail = "SELECT * FROM supplier_payment_detail
                WHERE SupplierPaymentDetailSupplierPaymentID = ?";
            $que_suppaymentdetail = $this->db->query($sql_suppaymentdetail, [$param['orderid']]);
            if (!$que_suppaymentdetail) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get data latest supplier payment detail");
                exit;
            }
            $suppayment_detail = $que_suppaymentdetail->result_array();

            $data_log = [
                "header" => $suppayment_header,
                "detail" => $suppayment_detail
            ];

            # LOG activity confirm payment #
            $messg = "Pembayaran Faktur No: {$suppayment_header['SupplierPaymentNumber']}";
            $messg .= " telah dikonfirmasi oleh {$users['M_UserUsername']} dengan nomor";
            $messg .= " pembayaran kasir: {$suppayment_header['SupplierPaymentCashierNumber']}";
            $this->insert_activity_log(
                "PF",
                "CONFIRM",
                $messg,
                $param['orderid'],
                $data_log,
                $users['M_UserID']
            );

            # INSERT JURNAL #
            $detail_transac = [];

            # GET data hutang #
            $sql_datahutang = "SELECT
                    SupplierPaymentNumber AS addonvalue,
                    SupplierPaymentDetailID,
                    jurnalTxCoaID AS coaID,
                    jurnalTxDescription AS coaDescription,
                    SupplierPaymentDetailAmount,
                    SupplierInvoiceDetailItemID
                FROM supplier_payment
                JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID
                JOIN supplier_invoice_detail ON SupplierInvoiceDetailSupplierInvoiceID = SupplierPaymentSupplierInvoiceID
                    AND SupplierInvoiceDetailIsActive = 'Y'
                JOIN jurnal_tx ON SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID
                WHERE SupplierPaymentID = ?
                AND SupplierPaymentDetailIsActive = 'Y'";
            $que_datahutang = $this->db->query($sql_datahutang, [$param['orderid']]);
            if (!$que_datahutang) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get data hutang item");
                exit;
            }
            $data_hutang = $que_datahutang->result_array();
            foreach ($data_hutang as $key => $debt) {
                $detail_transac[] = [
                    "coaID" => $debt['coaID'],
                    "coaDescription" => $debt['coaDescription'],
                    "debit" => $debt['SupplierPaymentDetailAmount'],
                    "credit" => 0,
                    "addoncode" => "JFA",
                    "addonvalue" => $debt['addonvalue'],
                    "addonitemid" => $debt['SupplierInvoiceDetailItemID']
                ];
            }

            # GET data bayar #
            $sql_databayar = "SELECT
                CONCAT('Jurnal Payment Invoice Nomor : ',
                    SupplierPaymentNumber, DATE_FORMAT(now(),
                    ', Tanggal : %d-%m-%Y ')
                ) AS jurnaltitle,
                CONCAT('Nomor pembayaran kasir : ',
                    SupplierPaymentCashierNumber,
                    ' dan Nomor grup pembayaran : ',
                    SupplierPaymentGroupNumber
                ) AS jurnaldesc,
                SupplierPaymentNumber AS no_payinv,
                SupplierPaymentCashierNumber AS addonvalue,
                SupplierPaymentCoaID AS coaID,
                coaDescription,
                SupplierPaymentAmount AS amount,
                SupplierPaymentRounding AS rounding,
                (SupplierPaymentAmount + SupplierPaymentRounding) AS bayar
            FROM supplier_payment
            JOIN coa ON coaID = SupplierPaymentCoaID
            WHERE SupplierPaymentID = ?";
            $que_databayar = $this->db->query($sql_databayar, [$param['orderid']]);
            if (!$que_databayar) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get data bayar");
                exit;
            }
            $data_bayar = $que_databayar->row_array();
            $detail_transac[] = [
                "coaID" => $data_bayar['coaID'],
                "coaDescription" => $data_bayar['coaDescription'],
                "debit" => 0,
                "credit" => abs($data_bayar['bayar']),
                "addoncode" => "PAYINVSG",
                "addonvalue" => $data_bayar['addonvalue'],
                "addonitemid" => 0
            ];

            # rugi / untung dari rounding #
            $sql_lossprofit = "SELECT coaID, coaDescription
            FROM coa WHERE coaAccountNo = ? AND coaIsActive = 'Y'";
            $data_round = doubleval($data_bayar['rounding']);
            if ($data_round > 0) {
                # loss #
                $que_lossprofit = $this->db->query($sql_lossprofit, ['6120402001']);
                if (!$que_lossprofit) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get data coa loss sisa kas");
                    exit;
                }
                $loss_coa = $que_lossprofit->row_array();

                $detail_transac[] = [
                    "coaID" => $loss_coa['coaID'],
                    "coaDescription" => $loss_coa['coaDescription'],
                    "debit" => abs($data_round),
                    "credit" => 0,
                    "addoncode" => "PAYINVSG",
                    "addonvalue" => $data_bayar['addonvalue'],
                    "addonitemid" => 0
                ];
            } elseif ($data_round < 0) {
                # profit #
                $que_lossprofit = $this->db->query($sql_lossprofit, ['6110500001']);
                if (!$que_lossprofit) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get data coa profit sisa kas");
                    exit;
                }
                $profit_coa = $que_lossprofit->row_array();

                $detail_transac[] = [
                    "coaID" => $profit_coa['coaID'],
                    "coaDescription" => $profit_coa['coaDescription'],
                    "debit" => 0,
                    "credit" => abs($data_round),
                    "addoncode" => "PAYINVSG",
                    "addonvalue" => $data_bayar['addonvalue'],
                    "addonitemid" => 0
                ];
            }

            $this->insertJurnal($users, $data_bayar, $detail_transac);

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

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

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

            # Generate number supplier payment #
            $sql_gennumber = "SELECT `fn_numbering`(?) as numberx";
            $paygroupnum = $this->db->query($sql_gennumber, ['PC'])->row()->numberx;

            if ($paygroupnum == '') {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] generate number group supplier payment");
                exit;
            }

            $rounding = 0;
            if (doubleval($param['xrounding'] > 0)) {
                $sisa = doubleval($param['xrounding']) - doubleval($param['total']);
                $rounding = round($sisa, 2);
            }


            $lastIndex = count($param['details']) - 1;
            # LOOP details invoice payment #
            foreach ($param['details'] as $idx => $obj) {
                $paynumber = $this->db->query($sql_gennumber, ['PN'])->row()->numberx;
                if ($paynumber == '') {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] generate number kasir supplier payment");
                    exit;
                }

                $SupplierPaymentID = $obj['SupplierPaymentID'];
                $SupplierInvoiceID = $obj['SupplierInvoiceID'];

                # CEK index invoice terakhir #
                $roundvalue = 0;
                if ($idx == $lastIndex) {
                    $roundvalue = $rounding;
                }

                # UPDATE header supplier payment #
                $sql_updateheader = "UPDATE supplier_payment SET
                    SupplierPaymentIsConfirm = 'Y',
                    SupplierPaymentConfirmUserID = ?,
                    SupplierPaymentGroupNumber = ?,
                    SupplierPaymentCashierNumber = ?,
                    SupplierPaymentRounding = ?,
                    SupplierPaymentConfirmDate = now(),
                    SupplierPaymentNote = ?,
                    SupplierPaymentCoaID = ?
                WHERE SupplierPaymentID = ?";
                $que_updateheader = $this->db->query($sql_updateheader, [
                    $users['M_UserID'],
                    $paygroupnum,
                    $paynumber,
                    $roundvalue,
                    $param['keterangan'],
                    $param['paymenttype'],
                    $SupplierPaymentID
                ]);
                if (!$que_updateheader) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update supplier payment header");
                    exit;
                }

                # UPDATE status lunas supplier invoice #
                $sql_suppinvoice = "UPDATE supplier_invoice
                SET SupplierInvoiceIsLunas = 'Y'
                WHERE SupplierInvoiceID = ?";
                $que_suppinvoice = $this->db->query($sql_suppinvoice, [$SupplierInvoiceID]);
                if (!$que_suppinvoice) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update status lunas invoice");
                    exit;
                }

                # GET Latest data supplier payment #
                $sql_suppayment = "SELECT * FROM supplier_payment WHERE SupplierPaymentID = ?";
                $que_suppayment = $this->db->query($sql_suppayment, [$SupplierPaymentID]);
                if (!$que_suppayment) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get data latest supplier payment");
                    exit;
                }
                $suppayment_header = $que_suppayment->row_array();

                $sql_suppaymentdetail = "SELECT * FROM supplier_payment_detail
                    WHERE SupplierPaymentDetailSupplierPaymentID = ?";
                $que_suppaymentdetail = $this->db->query($sql_suppaymentdetail, [$SupplierPaymentID]);
                if (!$que_suppaymentdetail) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get data latest supplier payment detail");
                    exit;
                }
                $suppayment_detail = $que_suppaymentdetail->result_array();

                $data_log = [
                    "header" => $suppayment_header,
                    "detail" => $suppayment_detail
                ];

                # LOG activity confirm payment #
                $messg = "Pembayaran Faktur No: {$suppayment_header['SupplierPaymentNumber']}";
                $messg .= " telah dikonfirmasi oleh {$users['M_UserUsername']} dengan nomor";
                $messg .= " pembayaran kasir: {$suppayment_header['SupplierPaymentCashierNumber']}";
                $this->insert_activity_log(
                    "PF",
                    "CONFIRM",
                    $messg,
                    $SupplierPaymentID,
                    $data_log,
                    $users['M_UserID']
                );

                ## INSERT jurnal ##
                $detail_transac = [];

                # GET data hutang #
                $sql_datahutang = "SELECT
                    SupplierPaymentNumber AS addonvalue,
                    SupplierPaymentDetailID,
                    jurnalTxCoaID AS coaID,
                    jurnalTxDescription AS coaDescription,
                    SupplierPaymentDetailAmount,
                    SupplierInvoiceDetailItemID
                FROM supplier_payment
                JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID
                JOIN supplier_invoice_detail ON SupplierInvoiceDetailSupplierInvoiceID = SupplierPaymentSupplierInvoiceID
                    AND SupplierInvoiceDetailIsActive = 'Y'
                JOIN jurnal_tx ON SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID
                WHERE SupplierPaymentID = ?
                AND SupplierPaymentDetailIsActive = 'Y'";
                $que_datahutang = $this->db->query($sql_datahutang, [$SupplierPaymentID]);
                if (!$que_datahutang) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get data hutang item");
                    exit;
                }
                $data_hutang = $que_datahutang->result_array();
                foreach ($data_hutang as $key => $debt) {
                    $detail_transac[] = [
                        "coaID" => $debt['coaID'],
                        "coaDescription" => $debt['coaDescription'],
                        "debit" => $debt['SupplierPaymentDetailAmount'],
                        "credit" => 0,
                        "addoncode" => "JFA",
                        "addonvalue" => $debt['addonvalue'],
                        "addonitemid" => $debt['SupplierInvoiceDetailItemID']
                    ];
                }

                # GET data bayar #
                $sql_databayar = "SELECT
                    CONCAT('Jurnal Payment Invoice Nomor : ',
                        SupplierPaymentNumber, DATE_FORMAT(now(),
                        ', Tanggal : %d-%m-%Y ')
                    ) AS jurnaltitle,
                    CONCAT('Nomor pembayaran kasir : ',
                        SupplierPaymentCashierNumber,
                        ' dan Nomor grup pembayaran : ',
                        SupplierPaymentGroupNumber
                    ) AS jurnaldesc,
                    SupplierPaymentNumber AS no_payinv,
                    SupplierPaymentGroupNumber AS addonvalue,
                    SupplierPaymentCoaID AS coaID,
                    coaDescription,
                    SupplierPaymentAmount AS amount,
                    SupplierPaymentRounding AS rounding,
                    (SupplierPaymentAmount + SupplierPaymentRounding) AS bayar
                FROM supplier_payment
                JOIN coa ON coaID = SupplierPaymentCoaID
                WHERE SupplierPaymentID = ?";
                $que_databayar = $this->db->query($sql_databayar, [$SupplierPaymentID]);
                if (!$que_databayar) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] get data bayar");
                    exit;
                }
                $data_bayar = $que_databayar->row_array();
                $detail_transac[] = [
                    "coaID" => $data_bayar['coaID'],
                    "coaDescription" => $data_bayar['coaDescription'],
                    "debit" => 0,
                    "credit" => abs($data_bayar['bayar']),
                    "addoncode" => "PAYINVGR",
                    "addonvalue" => $data_bayar['addonvalue'],
                    "addonitemid" => 0
                ];

                # rugi / untung dari rounding #
                $sql_lossprofit = "SELECT coaID, coaDescription
                FROM coa WHERE coaAccountNo = ? AND coaIsActive = 'Y'";
                $data_round = doubleval($data_bayar['rounding']);
                if ($data_round > 0) {
                    # loss #
                    $que_lossprofit = $this->db->query($sql_lossprofit, ['6120402001']);
                    if (!$que_lossprofit) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] get data coa loss sisa kas");
                        exit;
                    }
                    $loss_coa = $que_lossprofit->row_array();

                    $detail_transac[] = [
                        "coaID" => $loss_coa['coaID'],
                        "coaDescription" => $loss_coa['coaDescription'],
                        "debit" => abs($data_round),
                        "credit" => 0,
                        "addoncode" => "PAYINVGR",
                        "addonvalue" => $data_bayar['addonvalue'],
                        "addonitemid" => 0
                    ];
                } elseif ($data_round < 0) {
                    # profit #
                    $que_lossprofit = $this->db->query($sql_lossprofit, ['6110500001']);
                    if (!$que_lossprofit) {
                        $this->db->trans_rollback();
                        $this->sys_error_db("[Error] get data coa profit sisa kas");
                        exit;
                    }
                    $profit_coa = $que_lossprofit->row_array();

                    $detail_transac[] = [
                        "coaID" => $profit_coa['coaID'],
                        "coaDescription" => $profit_coa['coaDescription'],
                        "debit" => 0,
                        "credit" => abs($data_round),
                        "addoncode" => "PAYINVGR",
                        "addonvalue" => $data_bayar['addonvalue'],
                        "addonitemid" => 0
                    ];
                }

                $this->insertJurnal($users, $data_bayar, $detail_transac);
            }

            $this->db->trans_commit();
            $this->sys_ok("[Success] success multi payment invoice");
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    private function insertJurnal($users, $databayar, $detailtrx)
    {
        # GET periode jurnal #
        $sql_periode = "SELECT periodeID FROM periode
        WHERE DATE(NOW()) BETWEEN periodeStartDate AND periodeEndDate
            AND periodeIsActive = 'Y' AND periodeIsClosed = 'N'";
        $que_periode = $this->db->query($sql_periode, []);
        if (!$que_periode) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] find periode id");
            exit;
        }

        if ($que_periode->num_rows() === 0) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] Waktu periode tidak ditemukan");
            exit;
        }
        $JurnalPeriode = $que_periode->row_array()['periodeID'];

        # GENERATE nomor jurnal #
        $sql_jurnalno = "SELECT `fn_numbering`('J') AS jnumber";
        $que_jurnalno = $this->db->query($sql_jurnalno, []);
        if (!$que_jurnalno) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] generate jurnal number");
            exit;
        }
        $JurnalNumber = $que_jurnalno->row_array()['jnumber'];
        $JurnalTitle = $databayar['jurnaltitle'];
        $JurnalDescp = $databayar['jurnaldesc'];

        # GET jurnal type #
        $sql_jurnaltype = "SELECT JurnalTypeID FROM jurnal_type
        WHERE JurnalTypeCode = 'PAYMENTINV' AND JurnalTypeIsActive = 'Y'";
        $que_jurnaltype = $this->db->query($sql_jurnaltype, []);
        if (!$que_jurnaltype) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] get jurnal type");
            exit;
        }
        $JurnalType = $que_jurnaltype->row_array()['JurnalTypeID'];

        # INSERT jurnal header #
        $sql_insheader = "INSERT INTO jurnal (
            jurnalM_BranchCompanyID,
            JurnalS_RegionalID,
            jurnalM_BranchCode,
            jurnalperiodeID,
            jurnalNo,
            jurnalTitle,
            jurnalDescription,
            jurnalDate,
            jurnalJurnalTypeID,
            jurnalM_UserID
        ) VALUES (?,?,?,?,?,?,?,NOW(),?,?)";
        $que_inserjurnal = $this->db->query($sql_insheader, [
            $users['M_BranchCompanyID'],
            $users['S_RegionalID'],
            $users['M_BranchCode'],
            $JurnalPeriode,
            $JurnalNumber,
            $JurnalTitle,
            $JurnalDescp,
            $JurnalType,
            $users['M_UserID']
        ]);
        if (!$que_inserjurnal) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] insert jurnal header");
            exit;
        }
        $JurnalID = $this->db->insert_id();

        # INSERT jurnal tx #
        foreach ($detailtrx as $key => $trax) {
            $sql_trax = "INSERT INTO jurnal_tx (
                jurnalTxJurnalID,
                jurnalTxCoaID,
                jurnalTxDescription,
                jurnalTxDebit,
                jurnalTxCredit,
                jurnalTxM_UserID
            ) VALUES (?,?,?,?,?,?)";
            $que_trax = $this->db->query($sql_trax, [
                $JurnalID,
                $trax['coaID'],
                $trax['coaDescription'],
                $trax['debit'],
                $trax['credit'],
                $users['M_UserID']
            ]);
            if (!$que_trax) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] insert jurnal tx");
                exit;
            }
            $JurnalTxID = $this->db->insert_id();

            # INSERT jurnal addon #
            $sql_addon = "INSERT INTO jurnal_addon (
                jurnalAddOnJurnalID,
                jurnalAddOnJurnalTxID,
                jurnalAddOnCode,
                jurnalAddOnValue,
                jurnalAddOnM_ItemID,
                jurnalAddOnCreated,
                jurnalAddOnCreatedUserID
            ) VALUES (?,?,?,?,?,NOW(),?)";
            $que_addon = $this->db->query($sql_addon, [
                $JurnalID,
                $JurnalTxID,
                $trax['addoncode'],
                $trax['addonvalue'],
                $trax['addonitemid'],
                $users['M_UserID']
            ]);
            if (!$que_addon) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] insert jurnal addon");
                exit;
            }
        }
    }

    private function insert_activity_log($actcode, $status, $desc, $refID, $data, $userID)
    {
        $json = json_encode($data);
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->db->trans_rollback();
            $this->sys_error("[Error] encode data into json for log activity");
            exit;
        }

        $sql = "INSERT INTO user_activity(
            UserActivityCode,
            UserActivityStatus,
            UserActivityDescription,
            UserActivityRefID,
            UserActivityData,
            UserActivityUserID,
            UserActivityCreated
        ) VALUES (?,?,?,?,?,?,NOW())";
        $que = $this->db->query($sql, [
            $actcode,
            $status,
            $desc,
            $refID,
            $json,
            $userID
        ]);
        if (!$que) {
            $this->db->trans_rollback();
            $this->sys_error_db("[Error] insert into table log activity");
            exit;
        }
    }
}
