<?php

class Payment extends MY_Controller
{
   var $db_smartone;
   public function index()
   {
      echo "API";
   }
   
   public function __construct()
   {
      parent::__construct();
       $this->db_onedev = $this->load->database("onedev", true);
   }
   
   function lookup_type()
   {
	    //# cek token valid
        if (! $this->isLogin) {
        $this->sys_error("Invalid Token");
        exit;
        }
      $query = "SELECT coaID as id, 
				coaCode as code,
				'N' as chex,
				coaDescription as chexlabel,
				'Jumlah' as leftlabel,
				'' as selected_card,
				'' as selected_edc,
				'' as selected_account,
				CASE
					WHEN coaCode = 'CASH' THEN 'Kembali'
					WHEN coaCode = 'DEBIT' THEN 'Nomor Kartu'
					WHEN coaCode = 'CREDIT' THEN 'Nomor Kartu'
					WHEN coaCode = 'TRANSFER' THEN 'No. Rekening'
					ELSE 'Nomor Voucher'
				END as rightlabel,
				0 as leftvalue,
				0 as rightvalue
				FROM m_paymenttype WHERE coaIsActive = 'Y'";
	  $rows = $this->db_onedev->query($query)->result_array();
		foreach($rows as $k => $v){
			$rows[$k]['selected_card'] = array('id'=>0,'name'=>'');
			$rows[$k]['selected_edc'] = array('id'=>0,'name'=>'');
			$rows[$k]['selected_account'] = array('id'=>0,'name'=>'');
			if($v['chex'] == 'N')
				$rows[$k]['chex'] = false;
			else
				$rows[$k]['chex'] = true;
		}
      $result = array(
         "total" => count($rows) , 
         "records" => $rows, 
      ); 
      $this->sys_ok($result);
      exit;
   }
   function selectpaymenttypeold(){
	
		try {
			//# cek token valid
			if (! $this->isLogin) {
				$this->sys_error("Invalid Token");
				exit;
			}
			$rows = [];
			$query ="SELECT * FROM m_paymenttype 
					WHERE	
					coaIsActive = 'Y'";
					//echo $query;
			$rows['paymenttypes'] = $this->db_onedev->query($query)->result_array();
			
		
			$result = array(
				"total" => count($rows) , 
				"records" => $rows, 
			); 
			$this->sys_ok($result);
	
	
		} catch(Exception $exc) {
			$message = $exc->getMessage();
			$this->sys_error($message);
		}
		
	}
	function selectpaymenttype(){
	
		try {
			//# cek token valid
			if (! $this->isLogin) {
				$this->sys_error("Invalid Token");
				exit;
			}
			$rows = [];
			$regionalid = $this->sys_user['S_RegionalID'];
			$prm = $this->sys_input;
      $search = $prm["search"];
			$query ="SELECT coaID,	
coaAccountNo,	
coaDescription,
coaSubDescription
FROM coa 
JOIN s_regional ON S_RegionalID = $regionalid
JOIN m_branch ON M_BranchS_RegionalID = S_RegionalID
JOIN map_bank_coa ON MapBank_CoaID = coaID AND MapBank_BranchCode = M_BranchCode
WHERE	
coaIsActive = 'Y' AND
coaIsInput = 'Y' AND
coaAccountNo LIKE '111%' AND
coaAccountNo LIKE '11102%' AND
coaDescription LIKE '%{$search}%'

UNION
SELECT coaID,	
coaAccountNo,	
coaDescription,
coaSubDescription
FROM coa 
WHERE	
coaIsActive = 'Y' AND
coaIsInput = 'Y' AND
coaAccountNo LIKE '111%' AND
coaAccountNo NOT LIKE '11102%' AND
coaDescription LIKE '%{$search}%'
ORDER BY  coaAccountNo ASC";
					//echo $query;
			$rows['paymenttypes'] = $this->db_onedev->query($query)->result_array();
			
		
			$result = array(
				"total" => count($rows) , 
				"records" => $rows, 
			); 
			$this->sys_ok($result);
	
	
		} catch(Exception $exc) {
			$message = $exc->getMessage();
			$this->sys_error($message);
		}
		
	}
	function selectbank(){
		
			try {
				//# cek token valid
				if (! $this->isLogin) {
					$this->sys_error("Invalid Token");
					exit;
				}
				$rows = [];
				$query ="	SELECT * 
							FROM nat_bank
							WHERE
							Nat_BankIsActive = 'Y'
							ORDER BY Nat_BankCode DESC
						";
						//echo $query;
				$rows['banks'] = $this->db_onedev->query($query)->result_array();
				
			
				$result = array(
					"total" => count($rows) , 
					"records" => $rows, 
				); 
				$this->sys_ok($result);
		
		
			} catch(Exception $exc) {
				$message = $exc->getMessage();
				$this->sys_error($message);
			}
			
		}
		function selectaccount(){
			
				try {
					//# cek token valid
					if (! $this->isLogin) {
						$this->sys_error("Invalid Token");
						exit;
					}
					$rows = [];
					$query ="	SELECT M_BankAccountID as M_BankAccountID, CONCAT(Nat_BankCode,' (',M_BankAccountNo,')') as M_BankAccountName
                        FROM m_bank_account
						JOIN nat_bank ON M_BankAccountNat_BankID = Nat_BankID
                        WHERE
                        M_BankAccountIsActive = 'Y'
                        ORDER BY Nat_BankCode DESC";
							//echo $query;
					$rows['accounts'] = $this->db_onedev->query($query)->result_array();
					
				
					$result = array(
						"total" => count($rows) , 
						"records" => $rows, 
					); 
					$this->sys_ok($result);
			
			
				} catch(Exception $exc) {
					$message = $exc->getMessage();
					$this->sys_error($message);
				}
				
			}
   function lookup_banks()
   {
	    //# cek token valid
        if (! $this->isLogin) {
        $this->sys_error("Invalid Token");
        exit;
        }
      $query = "SELECT Nat_BankID as id, Nat_BankCode as name
                        FROM nat_bank
                        WHERE
                        Nat_BankIsActive = 'Y'
                        ORDER BY Nat_BankCode DESC";
	  $rows = $this->db_onedev->query($query)->result_array();
		
      $result = array(
         "total" => count($rows) , 
         "records" => $rows, 
      ); 
      $this->sys_ok($result);
      exit;
   }
   
   function lookup_accounts()
   {
	    //# cek token valid
        if (! $this->isLogin) {
        $this->sys_error("Invalid Token");
        exit;
        }
      $query = "SELECT M_BankAccountID as id, CONCAT(Nat_BankCode,' (',M_BankAccountNo,')') as name
                        FROM m_bank_account
						JOIN nat_bank ON M_BankAccountNat_BankID = Nat_BankID
                        WHERE
                        M_BankAccountIsActive = 'Y'
                        ORDER BY Nat_BankCode DESC";
	  $rows = $this->db_onedev->query($query)->result_array();
		
      $result = array(
         "total" => count($rows) , 
         "records" => $rows, 
      ); 
      $this->sys_ok($result);
      exit;
   }
   
   
   
   function searchcard(){
      if (! $this->isLogin) {
         $this->sys_error("Invalid Token");
         exit;
      }
      $prm = $this->sys_input;

      $max_rst = 12;
      $tot_count =0;

      $q = [
         'search'     => '%'
      ];

      if ($prm['search'] != '')
      {
         $q['search'] = "%{$prm['search']}%";
      }

      // QUERY TOTAL
      if($prm['search'] != ''){
		$sql = "
                        SELECT count(*) as total
                        FROM nat_bank
                        WHERE
                        Nat_BankName like ?
                        AND Nat_BankIsActive = 'Y'
                        ORDER BY Nat_BankName DESC
                  ";
	}
	else{
		$sql = "
                        SELECT count(*) as total
                        FROM nat_bank
                        WHERE
                        Nat_BankIsActive = 'Y'
                        ORDER BY Nat_BankName DESC
                  ";
	}
      $query = $this->db_onedev->query($sql,$q['search']);
      //echo $query;
      if ($query) {
         $tot_count = $query->result_array()[0]["total"];
      }
      else {
         $this->sys_error_db("m_city count",$this->db_onedev);
         exit;
      }
	if($prm['search'] != ''){
		$sql = "
                        SELECT Nat_BankID as id, Nat_BankName as name
                        FROM nat_bank
                        WHERE
                        Nat_BankName like ?
                        AND Nat_BankIsActive = 'Y'
                        ORDER BY Nat_BankName DESC
                  ";
	}
	else{
		$sql = "
                        SELECT Nat_BankID as id, Nat_BankName as name
                        FROM nat_bank
                        WHERE
                        Nat_BankIsActive = 'Y'
                        ORDER BY Nat_BankName DESC
                  ";
	}
      
      $query = $this->db_onedev->query($sql, array($q['search']));

      if ($query) {
         $rows = $query->result_array();
         //echo $this->db_onedev->last_query();
         $result = array("total" => $tot_count, "records" => $rows, "total_display" => sizeof($rows));
         $this->sys_ok($result);
      }
      else {
         $this->sys_error_db("m_city rows",$this->db_onedev);
         exit;
      }
   }

   
   function pay()
   {
		//# cek token valid
        if (! $this->isLogin) {
        $this->sys_error("Invalid Token");
        exit;
        }

        //# ambil parameter input
		$xuserid = $this->sys_user['M_UserID'];
		$prm = $this->sys_input;
		$orderid = $prm['orderid'];
		$payments = $prm['payments'];
		//$xnumber = $this->db_onedev->query("SELECT `fn_numbering`('PAY') as numberx")->row()->numberx;
		$sql = "INSERT INTO supplier_payment
		(SupplierPaymentSupplierInvoiceID,SupplierPaymentDate,SupplierPaymentCreated,SupplierPaymentUserID) 
		VALUES (?,CURDATE(),NOW(),?)";
		$query = $this->db_onedev->query($sql,
			array(
				$orderid, $xuserid
			)
		);

		if (!$query) {
			$this->sys_error_db("supplier_payment insert");
			exit;
		} 
		$headerid = $this->db_onedev->insert_id();
		//echo $headerid;
		
		foreach($payments as $k => $v){
			if($v['chex']){
				$actual = 0;
				$change = 0;
				$amount = $v['leftvalue'];
				if($v['code'] == 'CASH'){
					$actual = $v['leftvalue'];
					$change = $v['rightvalue'];
					if($actual > 0){
						$amount = intval($v['leftvalue']) - intval($v['rightvalue']);
					}
					else{
						$amount = $actual;
					}
					
					$sql = "CALL `sp_bill_payment_add_cash`(".$orderid.",".$amount.",".$amount.",".$headerid.",".$v['id'].",".$xuserid.")";					
					$query = $this->db_onedev->query($sql);
					
					if (!$query) {
						$this->sys_error_db("supplier_payment_detail cash insert");
						exit;
					}
					
				}
				else{
					if(intval($v['leftvalue']) > 0){
						$actual = 0;
						$change = 0;
						$amount = $v['leftvalue'];
						$selected_card = 0;
						$selected_edc = 0;
						$selected_account = 0;
						if($v['code'] == 'DEBIT' || $v['code'] == 'CREDIT' || $v['code'] == 'TRANSFER'){
							$selected_card = $v['selected_card']['id'];
							$selected_edc = $v['selected_edc']['id'];
							$selected_account = $v['selected_account']['id'];
						}
						$sql = "CALL `sp_bill_payment_add_noncash`(".$orderid.",".$amount.",".$amount.",".$headerid.",".$v['id'].",".$xuserid.",".$selected_card.",".$selected_edc.",".$selected_account.")";	
						//echo $sql;
						
						$query = $this->db_onedev->query($sql);
						//echo $this->db_onedev->last_query();
						if (!$query) {
							$this->sys_error_db("supplier_payment_detail non cash insert");
							exit;
						}
					}
				}
			}
		}
		
		$query = "SELECT coaID as id, 
					coaCode as code,
					IF(coaCode = 'CASH','Y','N') as chex,
					coaDescription as chexlabel,
					'Jumlah' as leftlabel,
					CASE
						WHEN coaCode = 'CASH' THEN 'Kembali'
						WHEN coaCode = 'DEBIT' THEN 'Nomor Kartu'
						WHEN coaCode = 'CREDIT' THEN 'Nomor Kartu'
						WHEN coaCode = 'TRANSFER' THEN 'Nomor Rekening'
						ELSE 'Nomor Voucher'
					END as rightlabel,
					0 as leftvalue,
					0 as rightvalue
					FROM m_paymenttype WHERE coaIsActive = 'Y'";
		$rows = $this->db_onedev->query($query)->result_array();
		
		foreach($rows as $k => $v){
			if($v['chex'] == 'N')
				$rows[$k]['chex'] = false;
			else
				$rows[$k]['chex'] = true;
		} 
		$xdata = $this->db_onedev->query("SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}")->row();
		$result = array(
			"total" => count($rows) , 
			"records" => array('types'=>$rows,'data'=>$xdata)
		); 
		$this->sys_ok($result);
		exit;
   }
   function paymanual()
   {
		//# cek token valid
        if (! $this->isLogin) {
        $this->sys_error("Invalid Token");
        exit;
        }

        //# ambil parameter input
		$xuserid = $this->sys_user['M_UserID'];
		$prm = $this->sys_input;
		$orderid = $prm['orderid'];
		$amount = $prm['amount'];
		$paymenttype = $prm['paymenttype'];
		$tanggalbayar = date('Y-m-d', strtotime($prm['tanggalbayar']));

		$totalbill = $prm['totalbill'];
		$paid = $prm['paid'];
		
		$keterangan = $prm['keterangan'];
		$bills = $prm['bills'];
		$xnumber = $this->db_onedev->query("SELECT `fn_numbering`('PINV') as numberx")->row()->numberx;
		$sql = "INSERT INTO supplier_payment
		(SupplierPaymentSupplierInvoiceID,
		SupplierPaymentNumber,
		SupplierPaymentDate,
		SupplierPaymentAmount,
		SupplierPaymentCoaID,	
		SupplierPaymentNote,
		SupplierPaymentCreated,
		SupplierPaymentUserID) 
		VALUES (?,
		?,
		CURDATE(),
		?,
		?,
		?,
		NOW(),
		?)";
		$query = $this->db_onedev->query($sql,
			array(
				$orderid,
				$xnumber,
				$amount,
				$paymenttype,
				$keterangan,
				$xuserid
			)
		);
		$headerid = $this->db_onedev->insert_id();
		if (!$query) {
			$this->sys_error_db("supplier_payment insert");
			exit;
		} else{
			$sqlbill = "UPDATE supplier_invoice SET 
			SupplierInvoiceDraftPaymentDate = '{$tanggalbayar}'
			WHERE SupplierInvoiceID = $orderid";
			$querybill = $this->db_onedev->query($sqlbill);
			
			//echo $this->db_onedev->last_query();

		}
		
		//echo $headerid;
		
		foreach($bills as $k => $v){
			if($v['tagihan_bayar'] > 0){
				$SupplierInvoiceDetailID = $v['SupplierInvoiceDetailID'];
				$tagihan_bayar = $v['tagihan_bayar'];
				$SupplierInvoiceDetailPurchaseOrderID = $v['SupplierInvoiceDetailPurchaseOrderID'];
					$sql = "INSERT INTO supplier_payment_detail(
						SupplierPaymentDetailSupplierPaymentID,	
						SupplierPaymentDetailSupplierInvoiceDetailID,	
						SupplierPaymentDetailAmount,	
						SupplierPaymentDetailUserID,	
						SupplierPaymentDetailCreated,
						SupplierPaymentDetailLastUpdated)
						VALUES(
						$headerid,
						$SupplierInvoiceDetailID,
						$tagihan_bayar,
						$xuserid,
						now(),
						now())";					
					$query = $this->db_onedev->query($sql);
					$billpaymentdetailid = $this->db_onedev->insert_id();
					if (!$query) {
						$this->sys_error_db("supplier_payment_detail cash insert");
						exit;
					}else{
						$sqlbilldetail = "UPDATE supplier_invoice_detail SET 
			SupplierInvoiceDetailUnpaid = SupplierInvoiceDetailUnpaid - $tagihan_bayar
			WHERE SupplierInvoiceDetailID = $SupplierInvoiceDetailID";
			$querybilldetail = $this->db_onedev->query($sqlbilldetail);

		/*	$sqlpayment = "INSERT INTO f_payment
				(F_PaymentPurchaseOrderID,
				F_PaymentDate,
				F_PaymentTotal,
				F_PaymentCreated,
				F_PaymentLastUpdated,
				F_PaymentM_UserID) 
				VALUES(
				$SupplierInvoiceDetailPurchaseOrderID,
				now(),
				$tagihan_bayar,
				now(),
				now(),
				$xuserid)";					
			$querypayment = $this->db_onedev->query($sqlpayment);
			$paymentid = $this->db_onedev->insert_id();
			$sqlpaymentdetail = "INSERT INTO f_paymentdetail
				(F_PaymentDetailF_PaymentID,
				F_PaymentDetailcoaID,	
				F_PaymentDetailAmount,
				F_PaymentDetailActual,
				F_PaymentDetailChange,	
				F_PaymentDetailEDCNat_BankID,
				F_PaymentDetailCardNat_BankID,	
				F_PaymentDetailM_BankAccountID,
				F_PaymentDetailCreated,	
				F_PaymentDetailLastUpdated,	
				F_PaymentDetailUserID) 
				VALUES(
					$paymentid,
					$paymenttype,
					$tagihan_bayar,
					$tagihan_bayar,
					0,
					$edc,
					$card,
					$account,
					now(),
					now(),
					$xuserid)";			
			//echo $sqlpaymentdetail;				
		$querypaymentdetail = $this->db_onedev->query($sqlpaymentdetail);

		$sqleditbillpaymentdetail = "UPDATE supplier_payment_detail SET 
		SupplierPaymentDetailF_PaymentID = $paymentid
		WHERE SupplierPaymentDetailID = $billpaymentdetailid";
		$queryeditbillpaymentdetail = $this->db_onedev->query($sqleditbillpaymentdetail);

		*/
					}
					
				
				}
			}
			$sql = "SELECT * FROM supplier_payment
                JOIN m_user ON M_UserID = SupplierPaymentUserID
                WHERE SupplierPaymentID = ?";
                $query = $this->db_onedev->query($sql, [$headerid]);
                $row = $query->row_array();

                $sql = "SELECT * FROM supplier_payment_detail
                WHERE SupplierPaymentDetailSupplierPaymentID = ?";
                $query = $this->db_onedev->query($sql, [$headerid]);
                $rows = $query->row_array();

                $data = array("header" => $row,
                "details" => $rows);
	$message = "Nomor Pembayaran Faktur: " . $row["SupplierPaymentNumber"] ." berhasil dibuat oleh " . $row["M_UserUsername"];
	$this->insert_act_log("PF", "NEW", $message, $headerid, $this->safeJsonEncode($data), $xuserid);
		
		$xdata = $this->db_onedev->query("SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}")->row();
		$result = array(
			"total" => count($rows) , 
			"records" => array('data'=>$xdata)
		); 
		$this->sys_ok($result);
		exit;
   }
   function editpaymanual()
   {
		//# cek token valid
        if (! $this->isLogin) {
        $this->sys_error("Invalid Token");
        exit;
        }

        //# ambil parameter input
		$xuserid = $this->sys_user['M_UserID'];
		$prm = $this->sys_input;
		$orderid = $prm['orderid'];
		$headerid = $prm['headerid'];
		$tanggalbayar = date('Y-m-d', strtotime($prm['tanggalbayar']));
			$sqlbill = "UPDATE supplier_invoice SET 
			SupplierInvoiceDraftPaymentDate = '{$tanggalbayar}'
			WHERE SupplierInvoiceID = $orderid";
			$querybill = $this->db_onedev->query($sqlbill);
			
			//echo $this->db_onedev->last_query();

		
	
			$sql = "SELECT * FROM supplier_payment
				JOIN supplier_invoice ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID
                JOIN m_user ON M_UserID = SupplierPaymentUserID
                WHERE SupplierPaymentID = ?";
                $query = $this->db_onedev->query($sql, [$headerid]);
                $row = $query->row_array();

                $sql = "SELECT * FROM supplier_payment_detail
                WHERE SupplierPaymentDetailSupplierPaymentID = ?";
                $query = $this->db_onedev->query($sql, [$headerid]);
                $rows = $query->row_array();

                $data = array("header" => $row,
                "details" => $rows);
	$message = "Nomor Pembayaran Faktur: " . $row["SupplierPaymentNumber"] ." berhasil diubah oleh " . $row["M_UserUsername"];
	$this->insert_act_log("PF", "NEW", $message, $headerid, $this->safeJsonEncode($data), $xuserid);
		
		$xdata = $this->db_onedev->query("SELECT SupplierPaymentID as idx, SupplierPaymentNumber as numberx FROM supplier_payment WHERE SupplierPaymentID = {$headerid}")->row();
		$result = array(
			"total" => count($rows) , 
			"records" => array('data'=>$xdata)
		); 
		$this->sys_ok($result);
		exit;
   }
   function delete_note()
   {
		//# cek token valid
        if (! $this->isLogin) {
        $this->sys_error("Invalid Token");
        exit;
        }

        //# ambil parameter input
		$xuserid = $this->sys_user['M_UserID'];
		$prm = $this->sys_input;
		$prmnota = $prm['nota'];

		$headerid = $prmnota['note_id'];
		$sql = "SELECT * FROM supplier_payment
                JOIN m_user ON M_UserID = SupplierPaymentUserID
                WHERE SupplierPaymentID = ?";
                $query = $this->db_onedev->query($sql, [$headerid]);
                $row = $query->row_array();

                $sql = "SELECT * FROM supplier_payment_detail
                WHERE SupplierPaymentDetailSupplierPaymentID = ?";
                $query = $this->db_onedev->query($sql, [$headerid]);
                $rows = $query->row_array();

                $data = array("header" => $row,
                "details" => $rows);

		$sql = "UPDATE supplier_payment 
		SET SupplierPaymentIsActive = 'N'
		WHERE SupplierPaymentID = {$prmnota['note_id']}";
		//echo $sql;
		$query = $this->db_onedev->query($sql);
		if (!$query) {
			$this->sys_error_db("supplier_payment delete");
			exit;
		} 
		
		$sql = "UPDATE supplier_payment_detail 
		SET SupplierPaymentDetailIsActive = 'N' 
		WHERE SupplierPaymentDetailSupplierPaymentID = {$prmnota['note_id']}";
		//echo $sql;
		$query = $this->db_onedev->query($sql);
		if (!$query) {
			$this->sys_error_db("supplier_payment_detail delete");
			exit;
		} 

		$sql = "UPDATE supplier_invoice 
		SET SupplierInvoiceUnpaid = SupplierInvoiceUnpaid + CAST({$prmnota['note_amount']} AS UNSIGNED)
		WHERE SupplierInvoiceID = {$prmnota['note_order_id']}";
		//echo $sql;
		$query = $this->db_onedev->query($sql);
		if (!$query) {
			$this->sys_error_db("supplier_invoice delete");
			exit;
		}

		$sql = "UPDATE supplier_invoice_detail 
		SET SupplierInvoiceDetailUnpaid = SupplierInvoiceDetailUnpaid + CAST({$prmnota['note_amount']} AS UNSIGNED)
		WHERE SupplierInvoiceDetailID = {$prmnota['detail_id']}";
		//echo $sql;
		$query = $this->db_onedev->query($sql);
		if (!$query) {
			$this->sys_error_db("supplier_invoice_detail delete");
			exit;
		}
		
	$message = "Nomor Pembayaran Faktur: " . $row["SupplierPaymentNumber"] ." telah dihapus oleh " . $row["M_UserUsername"];
	$this->insert_act_log("PF", "DELETE", $message, $headerid, $this->safeJsonEncode($data), $xuserid);
		$result = array(
			"total" => 1 , 
			"records" => array('prm'=>$prm)
		); 
		$this->sys_ok($result);
		exit;
   }
   function edit_note()
   {
		//# cek token valid
        if (! $this->isLogin) {
        $this->sys_error("Invalid Token");
        exit;
        }

        //# ambil parameter input
		$xuserid = $this->sys_user['M_UserID'];
		$prm = $this->sys_input;
		$id = $prm['id'];
		$inv_id = $prm['inv_id'];
		$detail_id = $prm['detail_id'];
		$paymenttype = $prm['paymenttype'];
		$amount_old = $prm['amount_old'];
		$amount_new = $prm['amount_new'];
		$keterangan = $prm['keterangan'];
		
		$datas_log = [];
		$messages_log = [];

		$sql = "SELECT *
                    FROM supplier_payment 
                    WHERE SupplierPaymentID = ?";
            $query = $this->db_onedev->query($sql, [$id]);
            if (!$query) {
                $this->db_onedev->trans_rollback();
                $this->sys_error_db("supplier payment", $this->db_onedev);
                exit;
            }
            $row = $query->row_array();

			if($row["SupplierPaymentAmount"]!= $amount_new) {
                $messages_log[] = "Perubahan pembayaran : " . $row["SupplierPaymentAmount"] . " menjadi " . $amount_new;
            }
            if($row["SupplierPaymentNote"]!= $keterangan) {
                $messages_log[] = "Perubahan keterangan : " . $row["SupplierPaymentNote"] . " menjadi " . $keterangan;
            }
			if($row["SupplierPaymentCoaID"]!= $paymenttype) {
                $messages_log[] = "Perubahan tipe pembayaran id  : " . $row["SupplierPaymentCoaID"] . " menjadi " . $paymenttype;
            }

            $datas_log['header'] = $row;

		$sql = "UPDATE supplier_payment SET 
		SupplierPaymentAmount = {$amount_new}, 
		SupplierPaymentNote = '{$keterangan}',
		SupplierPaymentCoaID = {$paymenttype},
		 SupplierPaymentUserID = {$xuserid}
		WHERE SupplierPaymentID = {$id}";
		//echo $sql;
		$query = $this->db_onedev->query($sql);
		if (!$query) {
			$this->sys_error_db("supplier_payment edit");
			exit;
		} 
		
		$sql = "UPDATE supplier_payment_detail 
		SET SupplierPaymentDetailAmount = {$amount_new},
		SupplierPaymentDetailUserID = {$xuserid}
		WHERE SupplierPaymentDetailSupplierPaymentID = {$id}";
		//echo $sql;
		$query = $this->db_onedev->query($sql);
		if (!$query) {
			$this->sys_error_db("supplier_payment_detail edit");
			exit;
		} 
		
		$sql = "UPDATE supplier_invoice 
		SET SupplierInvoiceUnpaid = (SupplierInvoiceUnpaid + $amount_old) - {$amount_new} 
		WHERE SupplierInvoiceID = {$inv_id}";
		//echo $sql;
		$query = $this->db_onedev->query($sql);
		if (!$query) {
			$this->sys_error_db("supplier_invoice edit");
			exit;
		}

		$sql = "UPDATE supplier_invoice_detail 
		SET SupplierInvoiceDetailUnpaid = (SupplierInvoiceDetailUnpaid + $amount_old) - {$amount_new} 
		WHERE SupplierInvoiceDetailID = {$detail_id}";
		//echo $sql;
		$query = $this->db_onedev->query($sql);
		if (!$query) {
			$this->sys_error_db("supplier_invoice_detail edit");
			exit;
		}
		if(count($messages_log) > 0) {
			$message = "Perubahan Pembayaran Faktur: " . $row["SupplierPaymentNumber"] . "\n";
			$message .= implode("\n", $messages_log);
		}else{
			$message = "Pembayaran Faktur: " . $row["SupplierPaymentNumber"] . " tanpa perubahan";
		}
		
		$datas_log = $this->convertNumericValuesToStrings($datas_log);
		$this->insert_act_log("PF", "EDIT", $message, $id, $this->safeJsonEncode($datas_log), $xuserid);
		$result = array(
			"total" => 1 , 
			"records" => array('prm'=>$prm)
		); 
		$this->sys_ok($result);
		exit;
   }
   function insert_act_log($code, $status, $description, $refId, $data, $userId)
    {
        $sql = "INSERT INTO user_activity(
                                UserActivityCode,
                                UserActivityStatus,
                                UserActivityDescription,
                                UserActivityRefID,
                                UserActivityData,
                                UserActivityUserID,
                                UserActivityCreated) 
                    VALUES (?,?,?,?,?,?,?)";
        $query = $this->db_onedev->query($sql, [$code, $status, $description, $refId, $data, $userId, date("Y-m-d H:i:s")]);
        if (!$query) {
            $this->sys_error_db("user activity", $this->db_onedev);
            exit;
        }
    }
    private function safeJsonEncode($data) {
        // Coba encode data ke JSON
        $jsonData = json_encode($data);
        
        // Cek apakah terjadi error saat encode
        if (json_last_error() !== JSON_ERROR_NONE) {
            $errorMsg = json_last_error_msg();
            error_log("JSON encode error: " . $errorMsg);
            
            // Lakukan sanitasi dan perbaikan data
            $fixedData = $this->fixJsonEncodeIssues($data, $errorMsg);
            
            // Coba encode lagi setelah diperbaiki
            $jsonData = json_encode($fixedData);
            
            // Jika masih error, log dan kembalikan objek kosong
            if (json_last_error() !== JSON_ERROR_NONE) {
                error_log("Failed to fix JSON encode issues: " . json_last_error_msg());
                // Kembalikan objek kosong jika masih gagal
                return '{}';
            }
        }
        
        return $jsonData;
    }

    // Fungsi untuk memperbaiki masalah encoding JSON
    private function fixJsonEncodeIssues($data, $errorMsg) {
        // Buat salinan data untuk dimodifikasi
        $fixedData = $data;
        
        // Tangani berbagai jenis error
        if (strpos($errorMsg, 'Malformed UTF-8') !== false) {
            // Perbaiki masalah karakter UTF-8
            $fixedData = $this->fixUTF8Issues($fixedData);
        } else if (strpos($errorMsg, 'Inf and NaN cannot be JSON encoded') !== false) {
            // Perbaiki masalah nilai Infinity atau NaN
            $fixedData = $this->fixInfNanIssues($fixedData);
        } else {
            // Konversi semua nilai numerik menjadi string untuk menghindari masalah presisi
            $fixedData = $this->convertNumericValuesToStrings($fixedData);
            
            // Perbaiki masalah referensi recursif
            $fixedData = $this->fixRecursiveReferences($fixedData);
        }
        
        return $fixedData;
    }

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

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

    // Perbaiki masalah referensi recursif
    private function fixRecursiveReferences($data, $depth = 0) {
        // Batasi kedalaman rekursi untuk menghindari infinite loop
        if ($depth > 50) {
            return "[MAX_DEPTH_REACHED]";
        }
        
        if (is_array($data)) {
            $result = [];
            foreach ($data as $key => $value) {
                if (is_array($value)) {
                    $result[$key] = $this->fixRecursiveReferences($value, $depth + 1);
                } else {
                    $result[$key] = $value;
                }
            }
            return $result;
        }
        
        return $data;
    }

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