<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Validator;
use Hidehalo\Nanoid\Client as Nanoid;
use GuzzleHttp\Client as GuzzleClient;
use App\Responses;
use App\Helper;
use App\Models\Users;
use App\Models\Banks;
use App\Models\Finance;
use App\Models\Orders;
use App\Models\OrdersAItems;
use App\Models\AItems;
use App\Models\UnitTypes;
use App\Models\OrdersTermins;
use App\Models\OrdersInvoices;
use App\Models\Vehicles;
use App\Models\Drivers;
use App\Models\OrdersItems;
use App\Models\OrdersDriversUploads;
use App\Models\Dana;
use App\Models\Checkpoints;
use App\Models\OrdersLogsTf;
use App\Models\OrdersCheckpoints;
use App\Models\DrvPhoneDevices;
use Barryvdh\DomPDF\Facade\Pdf;

class FinanceController extends Controller
{
	/**
	 * VIEW
	 */

	public function view_finance_download_invoice(Request $req)
	{
		// try {
		$now = time();
		$input = [
			'code' => $req->code,
		];
		$rulesInput = [
			'code' => 'required|numeric',
		];
		// validasi input
		$isValidInput = Validator::make($input, $rulesInput);
		if (!$isValidInput->passes()) {
			return abort(403, $isValidInput->messages()->first());
		}

		$ord_invc = OrdersInvoices::getByCode($req->code);
		if (count($ord_invc) < 1) {
			return abort(404, 'invoice not found');
		}
		if ($ord_invc[0]->is_gnrt_invc !== OrdersInvoices::IS_GNRT_INVC_YES) return abort(404, 'invoice not found');

		$filter = [
			'id' => $ord_invc[0]->ord_id,
			'get_checker_data' => 1,
			'get_prefer_type_truck' => 1,
			'get_additional_vehicles_info' => 1,
			'get_client_pt' => 1,
			'select_region_pck_drop' => 1,
			'get_pic_zone' => 1,
			'couple_pck_drop' => 1,
		];
		$order = Orders::showOrder($filter);
		if (count($order) < 1) {
			return abort(404, 'order not found');
		}

		if ($ord_invc[0]->ord_a_item_ids == null) {
			return abort(404, 'items not found');
		}
		// dd(implode(str_split($order[0]->c_pt_pic_phone_val, 4), ' '));

		$drvs_ups = OrdersDriversUploads::list([
			'ord_id' => $order[0]->ord_id,
			'pck_id' => $order[0]->ord_pck_id,
			'drop_id' => $order[0]->ord_drop_id,
			'ord_pck_drop_id' => $order[0]->ord_pck_drop_id,
		]);

		$data = [
			'ord_invc' => $ord_invc[0],
			'order' => $order[0],
			'drvs_ups' => $drvs_ups,
			'items' => OrdersAItems::showAItemByIds(explode(',', $ord_invc[0]->ord_a_item_ids)),
		];

		$pdf = PDF::loadView("menu_v2.Finance._printInvoice", $data);
		return $pdf->setPaper('a4', 'potrait')->stream('invoice.pdf');
		// return view("menu_v2.Finance._printInvoice", $data);
		// } catch (\Exception $e) {
		// 	$apiResp = Responses::error($e->getMessage());
		// 	return abort(500, $apiResp['meta']['message']);
		// }
	}

	public function view_ledger_balance(Request $req)
	{
		return view('menu_v2.Finance.ledgerBalance');
	}

	public function view_pocket_tf_history(Request $req)
	{
		$data = [];

		return view('menu_v2.Finance.pocket_tf_history', $data);
	}


	/**
	 * API
	 */
	public function api_finance_list_billings(Request $req)
	{
		try {
			$now = time();
			$input = [];
			$rulesInput = [];

			// validasi input
			// $isValidInput = Validator::make($input, $rulesInput);
			// if (!$isValidInput->passes()) {
			// 	$apiResp = Responses::bad_input($isValidInput->messages()->first());
			// 	return new Response($apiResp, $apiResp['meta']['code']);
			// }

			$filter = [
				'group_by' => 'ord_id',
			];
			if (($req->start_date != null && $req->start_date != '') && ($req->end_date != null && $req->end_date != '')) {
				$filter['start_date'] = $req->start_date;
				$filter['end_date'] = $req->end_date;
			}
			$list = Finance::listBillings($filter);
			$summary = Finance::summaryBillings($filter)[0] ?? new \StdClass();
			foreach ($list as $key => $row) {
				$list[$key]->DT_RowIndex = $key + 1;
				$list[$key]->action = '-';
				$list[$key]->main_item = "Pengantaran Logistik <br>" . ucwords(strtolower($row->pck_prid_name)) . " - " . ucwords(strtolower($row->drop_prid_name)) . " <br>" . date('d F Y', $row->set_pck_at);
			}

			$apiResp = Responses::success('success list billings');
			$apiResp['count'] = count($list);
			$apiResp['summary'] = [
				'total_billing' => $summary->total_billing ?? 0,
                'total_payed' => $summary->total_payed ?? 0,
                'total_remaining' => $summary->total_remaining ?? 0,
			];
			$apiResp['data'] = $list;
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_list_payments(Request $req)
	{
		try {
			$now = time();
			$input = [];
			$rulesInput = [];

			// validasi input
			// $isValidInput = Validator::make($input, $rulesInput);
			// if (!$isValidInput->passes()) {
			// 	$apiResp = Responses::bad_input($isValidInput->messages()->first());
			// 	return new Response($apiResp, $apiResp['meta']['code']);
			// }

			$filter = [
				'group_by' => 'ord_id',
			];
			if (($req->start_date != null && $req->start_date != '') && ($req->end_date != null && $req->end_date != '')) {
				$filter['start_date'] = $req->start_date;
				$filter['end_date'] = $req->end_date;
			}
			$list = Finance::listPayments($filter);
			$summary = Finance::summaryPayments($filter)[0] ?? new \StdClass();

			$newList = [];
			$cntK = 0;
			foreach ($list as $key => $row) {
				$list[$key]->action = '-';
				$list[$key]->main_item = "Pengantaran Logistik <br>" . ucwords(strtolower($row->pck_prid_name)) . " - " . ucwords(strtolower($row->drop_prid_name)) . " <br>" . date('d F Y', $row->set_pck_at);
				$isSame = 0;
				foreach ($newList as $nlK => $rowL) {
					if (!$row->ord_group_code) continue;
					if ($row->ord_group_code === $rowL->ord_group_code) {
						$isSame = 1;
						$newList[$nlK]->childs[] = clone $list[$key];
					}
				}
				if ($isSame) continue;
				$list[$key]->DT_RowIndex = ++$cntK;
				$list[$key]->childs = [];
				$newList[] = clone $list[$key];
			}

			$apiResp = Responses::success('success list payments');
			$apiResp['count'] = count($newList);
			$apiResp['summary'] = [
				'total_payment' => $summary->total_payment ?? 0,
                'total_payed' => $summary->total_payed ?? 0,
                'total_remaining' => $summary->total_remaining ?? 0,
			];
			$apiResp['data'] = $newList;
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_list_ledger_balances(Request $req)
	{
		try {
			$now = time();
			$input = [];
			$rulesInput = [];

			// validasi input
			// $isValidInput = Validator::make($input, $rulesInput);
			// if (!$isValidInput->passes()) {
			// 	$apiResp = Responses::bad_input($isValidInput->messages()->first());
			// 	return new Response($apiResp, $apiResp['meta']['code']);
			// }

			$filterList = [
				'with_items' => 1,
				'group_by' => 'ord_a_item.id',
			];
			$filterSum = [];
			if (($req->start_date != null && $req->start_date != '') && ($req->end_date != null && $req->end_date != '')) {
				$filterList['start_date'] = $req->start_date;
				$filterList['end_date'] = $req->end_date;
				$filterSum['start_date'] = $req->start_date;
				$filterSum['end_date'] = $req->end_date;
			}
			$list = Finance::listLedgerBl($filterList);
			$summary = Finance::summaryLedgerBl($filterSum)[0];

			// grouping & formatting v1
			$group_by_order_id = [];
			foreach ($list as $key => $row) {
				$row->amt_in = 0;
				$row->amt_out = 0;
				if ($row->a_item_type === OrdersAItems::A_TYPE_PRIMARY) {
					$row->item_desc = "Pengantaran Logistik <br>" . ucwords(strtolower($row->pck_prid_name)) . " - " . ucwords(strtolower($row->drop_prid_name)) . " <br>" . date('d F Y', $row->set_pck_at);
				}
				if ($row->calc_to_vdr === OrdersAItems::CALC_TO_VDR_YES) {
					$row->amt_out = $row->amt_total_flat;
				}
				if ($row->invc_to_client === OrdersAItems::INVC_TO_CLIENT_YES) {
					$row->amt_in = $row->amt_bill_total_flat;
				}
				$row->amt_bl = $row->amt_in - $row->amt_out;

				if (!isset($group_by_order_id[$row->ord_id])) {
					$group_by_order_id[$row->ord_id] = clone $row;
					$group_by_order_id[$row->ord_id]->a_items = [];
				}
				$group_by_order_id[$row->ord_id]->a_items[] = clone $row;
			}

			// grouping & formatting v2
			$new_group_by_order_id = [];
			$i = 0;
			foreach ($group_by_order_id as $key => $row) {
				$row->DT_RowIndex = ++$i;
				$row->action = '-';
				$new_group_by_order_id[] = clone $row;
			}

			$apiResp = Responses::success('success list ledger balance');
			$apiResp['count'] = count($new_group_by_order_id);
			$apiResp['summary'] = [
                'total_bl' => $summary->total_bl ?? 0,
                'total_in' => $summary->total_in ?? 0,
                'total_out' => $summary->total_out ?? 0,
			];
			// $apiResp['summary']['total_bl'] = $apiResp['summary']['total_in'] - $apiResp['summary']['total_out'];
			$apiResp['data'] = $new_group_by_order_id;
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_list_adt_items_payments(Request $req)
	{
		try {
			$now = time();
			$input = [
				'ord_id' => $req->ord_id,
			];
			$rulesInput = [
				// 'ord_id' => 'required|integer|not_in:0', // single
				'ord_id' => 'required|string',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$ord_ids = explode(',', $req->ord_id);

			$filter = [
				'group_by' => 'ord_a_item.id',
				'get_user_crt' => 1,
				'get_user_rjct' => 1,
			];
			if ($req->is_access_by_admin == 1) {
				$filter['is_access_by_admin'] = 1;
			}
			if ($ord_ids) {
				// $filter['ord_id'] = $ord_ids[0]; // single
				$filter['ord_ids'] = $ord_ids;
			}
			if ($req->is_aprv || $req->is_aprv == 0) {
				$filter['is_aprv'] = $req->is_aprv;
			}

			$list = Finance::listAdtItemsPayments($filter);
			// foreach ($list as $key => $row) {
			// 	$list[$key]->DT_RowIndex = $key + 1;
			// 	$list[$key]->action = '-';
			// 	// $list[$key]->main_item = "Pengantaran Logistik <br>" . ucwords(strtolower($row->pck_prid_name)) . " - " . ucwords(strtolower($row->drop_prid_name)) . " <br>" . date('d F Y', $row->set_pck_at);
			// }
			$newList = [];
			$cntK = 0;
			foreach ($list as $key => $row) {
				$list[$key]->action = '-';
				$isSame = 0;
				foreach ($newList as $nlK => $rowL) {
					// if ($req->is_access_by_admin == 1) continue;
					if (!$row->group_merge_code) continue;
					if ($row->group_merge_code === $rowL->group_merge_code) {
						$isSame = 1;
						$newList[$nlK]->childs[] = clone $list[$key];
					}
				}
				if ($isSame) continue;
				$list[$key]->DT_RowIndex = ++$cntK;
				$list[$key]->childs = [];
				if ($list[$key]->a_item_type === OrdersAItems::A_TYPE_PRIMARY && $list[$key]->stts_merge !== OrdersAItems::STTS_MERGE_RESULT) {
					$list[$key]->previous_termin = OrdersAItems::showAItem([
						'ord_id' => $list[$key]->ord_id,
						'is_active' => OrdersAItems::IS_ACTIVE_YES,
						'a_item_type' => OrdersAItems::A_TYPE_PRIMARY,
						'prev_main_item_id' => $list[$key]->ord_a_item_id,
						'v_termin_id_not_zero' => 1,
						'limit' => 1,
					]);
				}
				$newList[] = clone $list[$key];
			}

			$apiResp = Responses::success('success list adt items payments');
			$apiResp['count'] = count($newList);
			$apiResp['data'] = $newList;
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_add_a_items(Request $req)
	{
		/**
		 * Case
		 * Jika new item => a_id == "00"
		 * Jika without add new master item => a_id == "0"
		 * Jika is adm price == yes => no input tenggat pembayaran, bukti pengajuan, tujuan pembayaran(receiver)
		 * Jika slc_pay_purpose == fill => input tujuan pembayaran(receiver)n
		 * Jika status pembayaran == lunas => upload bukti pembayaran
		 */

		$url_submission_proof_base64 = [];
		$url_is_paid_proof_base64 = [];
		try {
			$now = time();

			$input = [
				'ord_id' => $req->ord_id,
				'flow_type' => $req->flow_type,
				'cash_type' => $req->cash_type,
				'a_id' => $req->a_id, // 0 => without add new and master, 00 => new
				'a_name' => $req->a_name,
				'a_type' => $req->a_type, // flag
				'a_price' => $req->a_price,
				'a_price_tax_type' => $req->a_price_tax_type,
				'a_price_tax_ppn_percent' => $req->a_price_tax_ppn_percent,
				'a_price_tax_ppn_flat' => $req->a_price_tax_ppn_flat,
				'a_price_tax_pph_percent' => $req->a_price_tax_pph_percent,
				'a_price_tax_pph_flat' => $req->a_price_tax_pph_flat,
				'a_price_total_tax' => $req->a_price_total_tax,
				'a_qty' => $req->a_qty,
				'a_invc_price' => $req->a_invc_price,
				'a_invc_price_tax_type' => $req->a_invc_price_tax_type,
				'a_invc_price_tax_ppn_percent' => $req->a_invc_price_tax_ppn_percent,
				'a_invc_price_tax_ppn_flat' => $req->a_invc_price_tax_ppn_flat,
				'a_invc_price_tax_pph_percent' => $req->a_invc_price_tax_pph_percent,
				'a_invc_price_tax_pph_flat' => $req->a_invc_price_tax_pph_flat,
				'a_invc_price_total_tax' => $req->a_invc_price_total_tax,
				'is_adm_price' => $req->is_adm_price,
				'ddln_pay_at' => $req->ddln_pay_at,
				'ddln_pay_type' => $req->ddln_pay_type, // flag
				'submission_proof_base64' => $req->submission_proof_base64,
				'slc_pay_purpose' => $req->slc_pay_purpose, // fill,none
				'bank_id' => $req->bank_id,
				'bank_code' => $req->bank_code,
				'bank_short' => $req->bank_short,
				'bank_name' => $req->bank_name,
				'bank_acc_number' => $req->bank_acc_number,
				'bank_acc_name' => $req->bank_acc_name,
				'is_paid' => $req->is_paid, // flag
				'paid_proof_ref_no' => $req->paid_proof_ref_no,
				'is_paid_proof_base64' => $req->is_paid_proof_base64,
				'is_paid_at' => $req->is_paid_at,
				'is_invc_to_client' => $req->is_invc_to_client, // flag
				'is_calc_to_vdr' => $req->is_calc_to_vdr, // flag
				'crt_type' => $req->crt_type, // flag
			];
			$rulesInput = [
				'ord_id' => 'required|integer|not_in:0',
				'flow_type' => 'required|integer|not_in:0',
				'cash_type' => 'required|integer|not_in:0',
				'a_id' => 'nullable|numeric', // 0 => without add new and master, 00 => new
				'a_name' => 'nullable|string',
				'a_type' => 'nullable|integer|min:0',
				'a_price' => 'nullable|numeric|min:0',
				'a_price_tax_type' => 'nullable|numeric|min:0',
				'a_price_tax_ppn_percent' => 'nullable|numeric|min:0',
				'a_price_tax_ppn_flat' => 'nullable|numeric|min:0',
				'a_price_tax_pph_percent' => 'nullable|numeric|min:0',
				'a_price_tax_pph_flat' => 'nullable|numeric',
				'a_price_total_tax' => 'nullable|numeric|min:0',
				'a_qty' => 'nullable|numeric|min:0',
				'a_invc_price' => 'nullable|numeric|min:0',
				'a_invc_price_tax_type' => 'nullable|numeric|min:0',
				'a_invc_price_tax_ppn_percent' => 'nullable|numeric|min:0',
				'a_invc_price_tax_ppn_flat' => 'nullable|numeric|min:0',
				'a_invc_price_tax_pph_percent' => 'nullable|numeric|min:0',
				'a_invc_price_tax_pph_flat' => 'nullable|numeric|min:0',
				'a_invc_price_total_tax' => 'nullable|numeric|min:0',
				'is_adm_price' => 'nullable|numeric',
				'ddln_pay_at' => 'nullable|numeric',
				'ddln_pay_type' => 'nullable|numeric', // flag
				'submission_proof_base64' => 'nullable|array',
				'slc_pay_purpose' => 'nullable|string', // fill,none
				'bank_id' => 'nullable|numeric',
				'bank_code' => 'nullable|numeric',
				'bank_short' => 'nullable|string',
				'bank_name' => 'nullable|string',
				'bank_acc_number' => 'nullable|numeric',
				'bank_acc_name' => 'nullable|string',
				'is_paid' => 'nullable|numeric', // flag
				'paid_proof_ref_no' => 'nullable|numeric',
				'is_paid_proof_base64' => 'nullable|array',
				'is_paid_at' => 'nullable|numeric',
				'is_invc_to_client' => 'nullable|numeric', // flag
				'is_calc_to_vdr' => 'nullable|numeric', // flag
				'crt_type' => 'nullable|numeric', // flag
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			if ($req->slc_pay_purpose == 'fill' && !$req->bank_id) {
				$apiResp = Responses::bad_input('informasi penerima wajib diisi');
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			if ($req->is_paid == OrdersAItems::IS_PAID_YES) {
				if ($req->is_paid_proof_base64 && count($req->is_paid_proof_base64) < 1) {
					$apiResp = Responses::bad_input('bukti pembayaran wajib diisi');
					return new Response($apiResp, $apiResp['meta']['code']);
				}
			}

			if ($req->submission_proof_base64 && count($req->submission_proof_base64) < 1) {
				$apiResp = Responses::bad_input('bukti pengajuan wajib diisi');
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$order = Orders::showOrder([
				'id' => $req->ord_id,
				// 'get_prefer_type_truck' => 1,
				'get_pic_zone' => 1,
				// 'get_stts_checker' => 1,
				// 'get_checker_data' => 1,
				// 'get_checker_user' => 1,
				// 'get_accidents' => 1,
				'get_client_pt' => 1,
			]);
			if (count($order) < 1) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			if ($req->auth->role === Users::ROLE_ADMIN) {
				$crt_type = AItems::CRT_TYPE_ADMIN;
			} else if ($req->auth->role === Users::ROLE_FINANCE) {
				$crt_type = AItems::CRT_TYPE_FINANCE;
			} else {
				$crt_type = 99;
			}

			if ($req->a_id === "00") {
				$uniqName = AItems::getByName($req->a_name, ['crt_type' => $crt_type]);
				if (count($uniqName) > 0) {
					$apiResp = Responses::bad_request('nama additional item sudah terdata');
					return (new Response($apiResp, $apiResp['meta']['code']));
				}
			}

			DB::beginTransaction();

			$a_id = $req->a_id;
			if ($req->a_id === "00") {
				$insAItems = [
					'name' => $req->a_name,
					'type' => $req->a_type,
					'price' => $req->a_price,
					'is_adm_price' => ($req->is_adm_price == OrdersAItems::IS_ADM_PRICE_YES) ? OrdersAItems::IS_ADM_PRICE_YES : OrdersAItems::IS_ADM_PRICE_NO,
					'is_active' => AItems::IS_ACTIVE,
					'crt' => $now,
					'crt_by' => $req->auth->uid,
					'crt_type' => $crt_type,
					'updt' => $now,
					'updt_by' => $req->auth->uid,
				];
				$a_id = AItems::add($insAItems);
				$a_item = AItems::getById($a_id);
			} else if ($req->a_id === "0") {
				$insAItems = [
					'name' => $req->a_name,
					'type' => $req->a_type,
					'price' => $req->a_price,
					'is_adm_price' => ($req->is_adm_price == OrdersAItems::IS_ADM_PRICE_YES) ? OrdersAItems::IS_ADM_PRICE_YES : OrdersAItems::IS_ADM_PRICE_NO,
					'is_active' => AItems::IS_ACTIVE,
					'crt' => $now,
					'crt_by' => $req->auth->uid,
					'crt_type' => $crt_type,
					'updt' => $now,
					'updt_by' => $req->auth->uid,
				];
			} else {
				$a_item = AItems::getById($a_id);
			}

			$insOrdersAItems = [
				'ord_id' => $order[0]->ord_id,
				'ord_code' => $order[0]->ord_code,
				'flow_type' => $req->flow_type,
				'cash_type' => $req->cash_type,
				'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
				'ref_ord_id' => $order[0]->ord_id,
				'ref_ord_code' => $order[0]->ord_code,
				'crt' => $now,
				'crt_by' => $req->auth->uid,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
			];
			// $insOrdersAItemsInvc = [];

			if ($req->a_id == "0") {
				$insOrdersAItems['desc'] = $insAItems['name'];
				$insOrdersAItems['unit_id'] = $a_id;
				$insOrdersAItems['unit_type'] = $insAItems['type'];
				$insOrdersAItems['amt_base_flat'] = $insAItems['price'];
				$insOrdersAItems['unit_qty'] = $req->a_qty;
			} else {
				$insOrdersAItems['desc'] = $a_item[0]->name;
				$insOrdersAItems['unit_id'] = $a_id;
				$insOrdersAItems['unit_type'] = $a_item[0]->type;
				$insOrdersAItems['amt_base_flat'] = $a_item[0]->price;
				$insOrdersAItems['unit_qty'] = $req->a_qty;
			}
			if (isset($req->a_price_tax_type)) {
				$insOrdersAItems['amt_tax_type'] = $req->a_price_tax_type;
				$insOrdersAItems['amt_tax_ppn_percent'] = $req->a_price_tax_ppn_percent ?? 0;
				$insOrdersAItems['amt_tax_ppn_flat'] = $req->a_price_tax_ppn_flat ?? 0;
				$insOrdersAItems['amt_tax_pph_percent'] = $req->a_price_tax_pph_percent ?? 0;
				$insOrdersAItems['amt_tax_pph_flat'] = $req->a_price_tax_pph_flat ?? 0;
				$insOrdersAItems['amt_total_tax_flat'] = $req->a_price_total_tax ?? 0;
			}
			if ($req->a_price_tax_type == OrdersAItems::AMT_TAX_TYPE_INCLUDE) {
				$insOrdersAItems['amt_result_flat'] = $req->a_price_total_tax;
				$insOrdersAItems['amt_total_flat'] = $req->a_price_total_tax * $req->a_qty;
			} else if ($req->a_price_tax_type == OrdersAItems::AMT_TAX_TYPE_WITHOUT) {
				$insOrdersAItems['amt_result_flat'] = $insOrdersAItems['amt_base_flat'];
				$insOrdersAItems['amt_total_flat'] = $insOrdersAItems['amt_base_flat'] * $req->a_qty;
			} else {
				$insOrdersAItems['amt_result_flat'] = $req->a_price_total_tax;
				$insOrdersAItems['amt_total_flat'] = $req->a_price_total_tax * $req->a_qty;
			}

			$req->a_invc_price = $req->a_invc_price ?? 0;
			$insOrdersAItems['amt_bill_base_flat'] = $req->a_invc_price;
			if (isset($req->a_invc_price_tax_type)) {
				$insOrdersAItems['amt_bill_tax_type'] = $req->a_invc_price_tax_type;
				$insOrdersAItems['amt_bill_tax_ppn_percent'] = $req->a_invc_price_tax_ppn_percent ?? 0;
				$insOrdersAItems['amt_bill_tax_ppn_flat'] = $req->a_invc_price_tax_ppn_flat ?? 0;
				$insOrdersAItems['amt_bill_tax_pph_percent'] = $req->a_invc_price_tax_pph_percent ?? 0;
				$insOrdersAItems['amt_bill_tax_pph_flat'] = $req->a_invc_price_tax_pph_flat ?? 0;
				$insOrdersAItems['amt_bill_total_tax_flat'] = $req->a_invc_price_total_tax ?? 0;
			}
			if ($req->a_invc_price_tax_type == OrdersAItems::AMT_TAX_TYPE_INCLUDE) {
				$insOrdersAItems['amt_bill_result_flat'] = $insOrdersAItems['amt_bill_base_flat'];
				$insOrdersAItems['amt_bill_total_flat'] = $insOrdersAItems['amt_bill_base_flat'] * $req->a_qty;
			} else if ($req->a_invc_price_tax_type == OrdersAItems::AMT_TAX_TYPE_WITHOUT) {
				$insOrdersAItems['amt_bill_result_flat'] = $insOrdersAItems['amt_bill_base_flat'];
				$insOrdersAItems['amt_bill_total_flat'] = $insOrdersAItems['amt_bill_base_flat'] * $req->a_qty;
			} else {
				$insOrdersAItems['amt_bill_result_flat'] = $req->a_invc_price_total_tax;
				$insOrdersAItems['amt_bill_total_flat'] = $req->a_invc_price_total_tax * $req->a_qty;
			}

			$insOrdersAItems['calc_to_vdr'] = OrdersAItems::CALC_TO_VDR_NO;
			if ($req->is_calc_to_vdr == OrdersAItems::CALC_TO_VDR_YES) {
				$insOrdersAItems['calc_to_vdr'] = OrdersAItems::CALC_TO_VDR_YES;
				$termins = OrdersTermins::listWithFilter([
					'ord_id' => $order[0]->ord_id,
					'termin_for' => OrdersTermins::TERMIN_FOR_VENDOR,
					'termin_is_paid' => OrdersTermins::IS_PAID_NO,
					'in_stts_merge' => [
						OrdersAItems::STTS_MERGE_NO,
						OrdersAItems::STTS_MERGE_RESULT,
					],
				]);
				$insOrdersAItems['v_termin_id'] = 0;
				$insOrdersAItems['ref_v_termin_id'] = 0;
				if (count($termins) > 0) {
					$insOrdersAItems['v_termin_id'] = $termins[0]->id;
					$insOrdersAItems['ref_v_termin_id'] = $termins[0]->id;
				}
				if ($insOrdersAItems['v_termin_id'] === 0) {
					$termins = OrdersTermins::listWithFilter([
						'ord_id' => $order[0]->ord_id,
						'termin_for' => OrdersTermins::TERMIN_FOR_VENDOR,
						'in_stts_merge' => [
							OrdersAItems::STTS_MERGE_NO,
							OrdersAItems::STTS_MERGE_RESULT,
						],
					]);
					$insOrdersAItems['v_termin_id'] = $termins[count($termins) - 1]->id;
					$insOrdersAItems['ref_v_termin_id'] = $termins[count($termins) - 1]->id;
				}
				$buy_price = $order[0]->buy_price + $insOrdersAItems['amt_total_flat'];
				Orders::updateOrder($order[0]->ord_id, [
					'buy_price' => $buy_price,
				]);
			}

			$insOrdersAItems['invc_to_client'] = OrdersAItems::INVC_TO_CLIENT_NO;
			if ($req->is_invc_to_client == OrdersAItems::INVC_TO_CLIENT_YES) {
				$insOrdersAItems['invc_to_client'] = OrdersAItems::INVC_TO_CLIENT_YES;
				$termins = OrdersTermins::listWithFilter([
					'ord_id' => $order[0]->ord_id,
					'termin_for' => OrdersTermins::TERMIN_FOR_CLIENT,
					'termin_is_paid' => OrdersTermins::IS_PAID_NO,
					'in_stts_merge' => [
						OrdersAItems::STTS_MERGE_NO,
						OrdersAItems::STTS_MERGE_RESULT,
					],
				]);
				$insOrdersAItems['c_termin_id'] = 0;
				$insOrdersAItems['ref_c_termin_id'] = 0;
				if (count($termins) > 0) {
					$insOrdersAItems['c_termin_id'] = $termins[0]->id;
					$insOrdersAItems['ref_c_termin_id'] = $termins[0]->id;
				}
				if ($insOrdersAItems['c_termin_id'] === 0) {
					DB::rollBack();
					$apiResp = Responses::bad_request('tidak dapat melakukan tagihan ke client, karena semua penagihan sudah close');
					return (new Response($apiResp, $apiResp['meta']['code']));
				}

				// calc perpajakan
				if ($termins[0]->termin_tax_type == OrdersAItems::AMT_TAX_TYPE_INCLUDE) {
					$before_ppn = round($insOrdersAItems['amt_bill_base_flat'] / OrdersAItems::PPN_PERCENT_INCLUDE);
					$ppn = round($insOrdersAItems['amt_bill_base_flat'] - $before_ppn);
					$amt_bill_base_tax_flat = round($before_ppn);
					$amt_bill_total_flat = round($amt_bill_base_tax_flat * $insOrdersAItems['unit_qty']);
					
					$insOrdersAItems['amt_bill_tax_type'] = $termins[0]->termin_tax_type;
					$insOrdersAItems['amt_bill_tax_ppn_percent'] = OrdersAItems::PPN_PERCENT;
					$insOrdersAItems['amt_bill_tax_ppn_flat'] = $ppn;
					$insOrdersAItems['amt_bill_tax_pph_percent'] = 0;
					$insOrdersAItems['amt_bill_tax_pph_flat'] = 0;
					$insOrdersAItems['amt_bill_total_tax_flat'] = $amt_bill_base_tax_flat;
					$insOrdersAItems['amt_bill_result_flat'] = $amt_bill_base_tax_flat;
					$insOrdersAItems['amt_bill_total_flat'] = $amt_bill_total_flat;
				}

				// if ($req->a_invc_price > 0) {
				// 	$insOrdersAItemsInvc = [
				// 		'ord_id' => $order[0]->ord_id,
				// 		'ord_code' => $order[0]->ord_code,
				// 		'flow_type' => $req->flow_type,
				// 		'cash_type' => $req->cash_type,
				// 		'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
				// 		'ref_ord_id' => $order[0]->ord_id,
				// 		'ref_ord_code' => $order[0]->ord_code,
				// 		'desc' => $insOrdersAItems['desc'],
				// 		'unit_id' => $insOrdersAItems['unit_id'],
				// 		'unit_type' => $insOrdersAItems['unit_type'],
				// 		'amt_base_flat' => $req->a_invc_price,
				// 		'unit_qty' => $insOrdersAItems['unit_qty'],
				// 		'amt_result_flat' => $req->a_invc_price,
				// 		'amt_total_flat' => $req->a_invc_price * $insOrdersAItems['unit_qty'],
				// 		'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_NO,
				// 		'v_termin_id' => 0,
				// 		'ref_v_termin_id' => 0,
				// 		'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_YES,
				// 		'c_termin_id' => $insOrdersAItems['c_termin_id'],
				// 		'ref_c_termin_id' => $insOrdersAItems['ref_c_termin_id'],
				// 		'crt' => $now,
				// 		'crt_by' => $req->auth->uid,
				// 		'updt' => $now,
				// 		'updt_by' => $req->auth->uid,
				// 	];
				// 	$insOrdersAItems['c_termin_id'] = 0;
				// 	$insOrdersAItems['ref_c_termin_id'] = 0;
				// 	$sell_price = $order[0]->price + $insOrdersAItemsInvc['amt_total_flat'];
				// } else {
				// 	$sell_price = $order[0]->price + $insOrdersAItems['amt_total_flat'];
				// }
				// cara lama sebelum perpajakan
				// $sell_price = $order[0]->price + $insOrdersAItems['amt_bill_total_flat'];
				// cara baru sebelum perpajakan
				$sell_price = $order[0]->price + $insOrdersAItems['amt_bill_base_flat'] * $insOrdersAItems['unit_qty'];

				Orders::updateOrder($order[0]->ord_id, [
					'price' => $sell_price,
				]);
				Finance::updtChangeInvc($insOrdersAItems['c_termin_id']);
			}

			$insOrdersAItems['only_client'] = OrdersAItems::ONLY_CLIENT_NO;
			// $insOrdersAItemsInvc['only_client'] = OrdersAItems::ONLY_CLIENT_NO;
			if ($req->only_client == OrdersAItems::ONLY_CLIENT_YES) {
				$insOrdersAItems['only_client'] = OrdersAItems::ONLY_CLIENT_YES;
				// $insOrdersAItemsInvc['only_client'] = OrdersAItems::ONLY_CLIENT_YES;
			}

			if ($req->is_adm_price == OrdersAItems::IS_ADM_PRICE_YES) {
				$insOrdersAItems['is_adm_price'] = OrdersAItems::IS_ADM_PRICE_YES;
			} else {
				$insOrdersAItems['ddln_pay_at'] = $req->ddln_pay_at ?? 0;
				$insOrdersAItems['ddln_pay_type'] = $req->ddln_pay_type ?? OrdersAItems::DDLN_PAY_TYPE_TIME;
				if ($req->slc_pay_purpose == 'fill' && $req->bank_id) {
					$insOrdersAItems['bank_id'] = $req->bank_id;
					$insOrdersAItems['bank_code'] = $req->bank_code;
					$insOrdersAItems['bank_short_name'] = $req->bank_short;
					$insOrdersAItems['bank_name'] = $req->bank_name;
					$insOrdersAItems['bank_acc_name'] = $req->bank_acc_name;
					$insOrdersAItems['bank_acc_number'] = $req->bank_acc_number;
				}
			}

			if ($req->is_paid == OrdersAItems::IS_PAID_YES) {
				$insOrdersAItems['is_paid'] = OrdersAItems::IS_PAID_YES;
				$insOrdersAItems['paid_ref_no'] = $req->paid_proof_ref_no;
				$insOrdersAItems['paid_at'] = $now;
				$insOrdersAItems['paid_by'] = $req->auth->uid;
			}

			if ($req->crt_type == OrdersAItems::CRT_TYPE_SYSTEM) {
				$insOrdersAItems['crt_type'] = OrdersAItems::CRT_TYPE_SYSTEM;
			} else if ($req->crt_type == OrdersAItems::CRT_TYPE_FINANCE) {
				$insOrdersAItems['crt_type'] = OrdersAItems::CRT_TYPE_FINANCE;
			} else {
				$insOrdersAItems['crt_type'] = OrdersAItems::CRT_TYPE_ADMIN;
			}
			// $insOrdersAItemsInvc['crt_type'] = $insOrdersAItems['crt_type'];

			$oa_id = OrdersAItems::add($insOrdersAItems);
			// if (count($insOrdersAItemsInvc) > 0) {
			// 	$insOrdersAItemsInvc['ref_ord_a_item_id'] = $oa_id;
			// 	$oa_id2 = OrdersAItems::add($insOrdersAItemsInvc);
			// }

			if ($req->is_adm_price == OrdersAItems::IS_ADM_PRICE_YES) {} else {
				if ($req->submission_proof_base64 && count($req->submission_proof_base64) > 0) {
					foreach ($req->submission_proof_base64 as $i => $img) {
						$clearBase64 = preg_replace('/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/', '', $img);
						$type = 'jpeg';
						if (strpos($img, 'application/pdf') !== false) $type = 'pdf';
						$url_submission_proof_base64[$i] = "orders/" . $order[0]->ord_id . "/a_items/" . $oa_id . "/submission/" . $req->auth->uid . "/submission_proof_img_$now" . "_" . "$i.$type";
						if (!Storage::disk('public')->put($url_submission_proof_base64[$i], base64_decode($clearBase64))) {
							DB::rollBack();
							$apiResp = Responses::bad_request('gagal upload bukti pengajuan');
							return (new Response($apiResp, $apiResp['meta']['code']));
						}
					}
				}
			}

			if ($req->is_paid == OrdersAItems::IS_PAID_YES) {
				if ($req->is_paid_proof_base64 && count($req->is_paid_proof_base64) > 0) {
					foreach ($req->is_paid_proof_base64 as $i => $img) {
						$clearBase64 = preg_replace('/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/', '', $img);
						$type = 'jpeg';
						if (strpos($img, 'application/pdf') !== false) $type = 'pdf';
						$url_is_paid_proof_base64[$i] = "orders/" . $order[0]->ord_id . "/a_items/" . $oa_id . "/payments/" . $req->auth->uid . "/payments_proof_img_$now" . "_" . "$i.$type";
						if (!Storage::disk('public')->put($url_is_paid_proof_base64[$i], base64_decode($clearBase64))) {
							DB::rollBack();
							$apiResp = Responses::bad_request('gagal upload bukti pembayaran');
							return (new Response($apiResp, $apiResp['meta']['code']));
						}
					}
				}
			}

			OrdersAItems::updt($oa_id, [
				'img_proof_submission' => (count($url_submission_proof_base64) > 0) ? json_encode($url_submission_proof_base64) : null,
				'img_proof_payment' => (count($url_is_paid_proof_base64) > 0) ? json_encode($url_is_paid_proof_base64) : null,
			]);
			// OrdersAItems::updt($oa_id2, [
			// 	'img_proof_submission' => (count($url_submission_proof_base64) > 0) ? json_encode($url_submission_proof_base64) : null,
			// 	'img_proof_payment' => (count($url_is_paid_proof_base64) > 0) ? json_encode($url_is_paid_proof_base64) : null,
			// ]);

			$apiResp = Responses::created('success add item');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			if (count($url_submission_proof_base64) > 0) {
				foreach ($url_submission_proof_base64 as $path) {
					Storage::disk('public')->delete($path);
				}
			}
			if (count($url_is_paid_proof_base64) > 0) {
				foreach ($url_is_paid_proof_base64 as $path) {
					Storage::disk('public')->delete($path);
				}
			}
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_show_a_item(Request $req, $ord_a_item_id)
	{
		try {
			$now = time();

			$input = [
				'ord_a_item_id' => $ord_a_item_id,
			];
			$rulesInput = [
				'ord_a_item_id' => 'required|integer|not_in:0',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$filter = [
				'ord_a_item_id' => $ord_a_item_id,
				'get_user_crt' => 1,
				'get_user_rjct' => 1,
			];
			$item = OrdersAItems::showAItem($filter);
			if (count($item) < 1) {
				$apiResp = Responses::not_found('item not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			if ($item[0]->group_merge_code) {
				$filter = [
					'exclude_ord_a_item_id' => $ord_a_item_id,
					'group_merge_code' => $item[0]->group_merge_code,
					'get_user_crt' => 1,
					'get_user_rjct' => 1,
				];
				$childs = OrdersAItems::showAItem($filter);
				$item[0]->childs = $childs;
			}

			$apiResp = Responses::success('success get detail item');
			$apiResp['data'] = $item[0];
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_pay_a_items(Request $req, $ord_a_item_id)
	{
		$url_up_paid_proof_base64 = [];
		try {
			$now = time();

			$input = [
				'ord_a_item_id' => $ord_a_item_id,
				// 'group_merge_code' => $req->group_merge_code,
				'up_paid_ref_no' => $req->up_paid_ref_no,
				'up_paid_proof_base64' => $req->up_paid_proof_base64,
			];
			$rulesInput = [
				'ord_a_item_id' => 'required|integer|not_in:0',
				// 'group_merge_code' => 'nullable|integer|not_in:0',
				'up_paid_ref_no' => 'required|numeric|min:0',
				'up_paid_proof_base64' => 'nullable|array',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			if (!$req->up_paid_proof_base64 || count($req->up_paid_proof_base64) < 1) {
				$apiResp = Responses::bad_input('bukti pembayaran wajib diisi');
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$a_item = OrdersAItems::showAItemById($ord_a_item_id);
			if (count($a_item) < 1) {
				$apiResp = Responses::not_found('item not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$order = Orders::showOrder(['id' => $a_item[0]->ord_id]);

			DB::beginTransaction();

			$updtOrdersAItems = [
				'paid_ref_no' => $req->up_paid_ref_no,
				'is_paid' => OrdersAItems::IS_PAID_YES,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
				'paid_at' => $now,
				'paid_by' => $req->auth->uid,
			];

			if ($a_item[0]->v_termin_id !== 0 && $a_item[0]->a_item_type === OrdersAItems::A_TYPE_PRIMARY) {
				$termin = OrdersTermins::getById($a_item[0]->v_termin_id);
				if ($termin[0]->termin_is_paid !== OrdersTermins::IS_PAID_YES) {
					OrdersTermins::updt($a_item[0]->v_termin_id, [
						'termin_is_paid' => OrdersTermins::IS_PAID_YES,
						'termin_paid_at' => $now,
						'termin_paid_by' => $req->auth->uid,
						'updt' => $now,
						'updt_by' => $req->auth->uid,
					]);
				}
			}

			if ($req->up_paid_proof_base64 && count($req->up_paid_proof_base64) > 0) {
				foreach ($req->up_paid_proof_base64 as $i => $img) {
					$clearBase64 = preg_replace('/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/', '', $img);
					$type = 'jpeg';
					if (strpos($img, 'application/pdf') !== false) $type = 'pdf';
					$url_up_paid_proof_base64[$i] = "orders/" . $a_item[0]->ord_id . "/a_items/" . $ord_a_item_id . "/payments/" . $req->auth->uid . "/payments_proof_img_$now" . "_" . "$i.$type";
					if (!Storage::disk('public')->put($url_up_paid_proof_base64[$i], base64_decode($clearBase64))) {
						DB::rollBack();
						$apiResp = Responses::bad_request('gagal upload bukti pembayaran');
						return (new Response($apiResp, $apiResp['meta']['code']));
					}
				}
			}
			$updtOrdersAItems['img_proof_payment'] = (count($url_up_paid_proof_base64) > 0) ? json_encode($url_up_paid_proof_base64) : null;

			OrdersAItems::updt($ord_a_item_id, $updtOrdersAItems);
			
			$updtOrd = [];

			$checkPaidOff = Finance::checkJustPaidOff($a_item[0]->ord_id);
			if ($checkPaidOff['invc_paid'] === 1) {
				$updtOrd['is_invc_paid'] = Orders::IS_PAID_YES;
				$updtOrd['invc_paid_at'] = $now;
			}
			if ($checkPaidOff['vdr_paid'] === 1) {
				$updtOrd['is_vdr_paid'] = Orders::IS_PAID_YES;
				$updtOrd['vdr_paid_at'] = $now;
				// kalau vhc & driver bisa order lagi setelah pembayaran lunas
				// Vehicles::updateVehicle($order[0]->vhc_id, [
				// 	'is_in_ord' => Vehicles::IN_ORD_NO,
				// 	'ord_id' => 0,
				// 	'ord_code' => 0,
				// ]);
				// Drivers::updateDriver($order[0]->drv_id, [
				// 	'is_in_ord' => Drivers::IN_ORD_NO,
				// 	'ord_id' => 0,
				// 	'ord_code' => 0,
				// ]);
			}
			if ($checkPaidOff['invc_vdr_paid'] === 1 || $checkPaidOff['invc_vdr_paid'] === 2) {
				if ($order[0]->status === Orders::STTS_DROP || $order[0]->status === Orders::STTS_CLIENT_PAY || $order[0]->status === Orders::STTS_VENDOR_PAYED) {
					$updtOrd['status'] = Orders::STTS_CLOSE;
				}
			}

			if (count($updtOrd) > 0) {
				Orders::updateOrder($a_item[0]->ord_id, $updtOrd);
			}

			// $currentBill = Finance::listBillings(['ord_id' => $a_item[0]->ord_id]);
			// $currentPay = Finance::listPayments(['ord_id' => $a_item[0]->ord_id]);
			// if ($currentBill[0]->total_billing === $currentBill[0]->total_payed || $currentPay[0]->total_payment === $currentPay[0]->total_payed) {
			// 	$updtOrd = [];
			// 	if ($currentBill[0]->total_billing === $currentBill[0]->total_payed) {
			// 		if ($order[0]->is_invc_paid !== Orders::IS_PAID_YES) {
			// 			$updtOrd['is_invc_paid'] = Orders::IS_PAID_YES;
			// 			$updtOrd['invc_paid_at'] = $now;
			// 		}
			// 	}
			// 	if ($currentPay[0]->total_payment === $currentPay[0]->total_payed) {
			// 		if ($order[0]->is_vdr_paid !== Orders::IS_PAID_YES) {
			// 			$updtOrd['is_vdr_paid'] = Orders::IS_PAID_YES;
			// 			$updtOrd['vdr_paid_at'] = $now;
			// 			Vehicles::updateVehicle($order[0]->vhc_id, [
			// 				'is_in_ord' => Vehicles::IN_ORD_NO,
			// 				'ord_id' => 0,
			// 				'ord_code' => 0,
			// 			]);
			// 			Drivers::updateDriver($order[0]->drv_id, [
			// 				'is_in_ord' => Drivers::IN_ORD_NO,
			// 				'ord_id' => 0,
			// 				'ord_code' => 0,
			// 			]);
			// 		}
			// 	}
			// 	if ($currentBill[0]->total_billing === $currentBill[0]->total_payed && $currentPay[0]->total_payment === $currentPay[0]->total_payed) {
			// 		$updtOrd['status'] = Orders::STTS_CLOSE;
			// 	}
			// 	if (count($updtOrd) > 0) {
			// 		Orders::updateOrder($a_item[0]->ord_id, $updtOrd);
			// 	}
			// }

			$apiResp = Responses::success('success pay item');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			if (count($url_up_paid_proof_base64) > 0) {
				foreach ($url_up_paid_proof_base64 as $path) {
					Storage::disk('public')->delete($path);
				}
			}
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_updt_a_items(Request $req, $ord_a_item_id)
	{
		/**
		 * Case
		 * Jika without add updt master item => a_id == "0" || "00"
		 * Jika is adm price == yes => no input tenggat pembayaran, bukti pengajuan, tujuan pembayaran(receiver)
		 * Jika slc_pay_purpose == fill => input tujuan pembayaran(receiver)n
		 * Jika status pembayaran == lunas => upload bukti pembayaran
		 */

		$url_submission_proof_base64 = [];
		$url_is_paid_proof_base64 = [];
		try {
			$now = time();

			$input = [
				'ord_a_item_id' => $req->ord_a_item_id,
				'flow_type' => $req->flow_type,
				'cash_type' => $req->cash_type,
				'a_id' => $req->a_id, // 0 => without update new and master, 00 => new
				'a_name' => $req->a_name,
				'a_type' => $req->a_type, // flag
				'a_price' => $req->a_price,
				'a_qty' => $req->a_qty,
				'a_invc_price' => $req->a_invc_price,
				'is_adm_price' => $req->is_adm_price,
				'ddln_pay_at' => $req->ddln_pay_at,
				'ddln_pay_type' => $req->ddln_pay_type, // flag
				'submission_proof_base64' => $req->submission_proof_base64,
				'slc_pay_purpose' => $req->slc_pay_purpose, // fill,none
				'bank_id' => $req->bank_id,
				'bank_code' => $req->bank_code,
				'bank_short' => $req->bank_short,
				'bank_name' => $req->bank_name,
				'bank_acc_number' => $req->bank_acc_number,
				'bank_acc_name' => $req->bank_acc_name,
				'is_paid' => $req->is_paid, // flag
				'is_paid_proof_base64' => $req->is_paid_proof_base64,
				'is_paid_at' => $req->is_paid_at,
				'is_invc_to_client' => $req->is_invc_to_client, // flag
				'is_calc_to_vdr' => $req->is_calc_to_vdr, // flag
				'crt_type' => $req->crt_type, // flag
			];
			$rulesInput = [
				'ord_a_item_id' => 'required|integer|not_in:0',
				'flow_type' => 'required|integer|not_in:0',
				'cash_type' => 'required|integer|not_in:0',
				'a_id' => 'nullable|numeric', // 0 => without update new and master, 00 => new
				'a_name' => 'nullable|string',
				'a_type' => 'nullable|integer|min:0',
				'a_price' => 'nullable|numeric|min:0',
				'a_qty' => 'nullable|numeric|min:0',
				'a_invc_price' => 'nullable|numeric|min:0',
				'is_adm_price' => 'nullable|numeric',
				'ddln_pay_at' => 'nullable|numeric',
				'ddln_pay_type' => 'nullable|numeric', // flag
				'submission_proof_base64' => 'nullable|array',
				'slc_pay_purpose' => 'nullable|string', // fill,none
				'bank_id' => 'nullable|numeric',
				'bank_code' => 'nullable|numeric',
				'bank_short' => 'nullable|string',
				'bank_name' => 'nullable|string',
				'bank_acc_number' => 'nullable|numeric',
				'bank_acc_name' => 'nullable|string',
				'is_paid' => 'nullable|numeric', // flag
				'is_paid_proof_base64' => 'nullable|array',
				'is_paid_at' => 'nullable|numeric',
				'is_invc_to_client' => 'nullable|numeric', // flag
				'is_calc_to_vdr' => 'nullable|numeric', // flag
				'crt_type' => 'nullable|numeric', // flag
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			if ($req->slc_pay_purpose == 'fill' && !$req->bank_id) {
				$apiResp = Responses::bad_input('informasi penerima wajib diisi');
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			if ($req->is_paid == OrdersAItems::IS_PAID_YES) {
				if ($req->is_paid_proof_base64 && count($req->is_paid_proof_base64) < 1) {
					$apiResp = Responses::bad_input('bukti pembayaran wajib diisi');
					return new Response($apiResp, $apiResp['meta']['code']);
				}
			}

			if ($req->submission_proof_base64 && count($req->submission_proof_base64) < 1) {
				$apiResp = Responses::bad_input('bukti pengajuan wajib diisi');
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$orderAItem = OrdersAItems::getById($ord_a_item_id);
			if (count($orderAItem) < 1) {
				$apiResp = Responses::not_found('item not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$order = Orders::showOrder([
				'id' => $req->ord_id,
				// 'get_prefer_type_truck' => 1,
				'get_pic_zone' => 1,
				// 'get_stts_checker' => 1,
				// 'get_checker_data' => 1,
				// 'get_checker_user' => 1,
				// 'get_accidents' => 1,
				'get_client_pt' => 1,
			]);
			if (count($order) < 1) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			// if ($req->a_id === "00") {
			// 	$filterUniqName = [];
			// 	if ($req->auth->role === Users::ROLE_ADMIN) {
			// 		$filterUniqName['crt_type'] = AItems::CRT_TYPE_ADMIN;
			// 	} else if ($req->auth->role === Users::ROLE_FINANCE) {
			// 		$filterUniqName['crt_type'] = AItems::CRT_TYPE_FINANCE;
			// 	} else {
			// 		$filterUniqName['crt_type'] = 99;
			// 	}

			// 	$uniqName = AItems::getByName($req->a_name, $filterUniqName);
			// 	if (count($uniqName) > 0) {
			// 		$apiResp = Responses::bad_request('nama additional item sudah terdata');
			// 		return (new Response($apiResp, $apiResp['meta']['code']));
			// 	}
			// }

			DB::beginTransaction();

			$a_id = $req->a_id;
			if ($req->a_id == "0" || $req->a_id == "00") {
				$updtAItems = [
					'name' => $req->a_name,
					'type' => $req->a_type,
					'price' => $req->a_price,
					'is_adm_price' => ($req->is_adm_price == OrdersAItems::IS_ADM_PRICE_YES) ? OrdersAItems::IS_ADM_PRICE_YES : OrdersAItems::IS_ADM_PRICE_NO,
					'is_active' => AItems::IS_ACTIVE,
					'updt' => $now,
					'updt_by' => $req->auth->uid,
				];
			} else {
				$updtAItems = [
					'name' => $req->a_name,
					'type' => $req->a_type,
					'price' => $req->a_price,
					'is_adm_price' => ($req->is_adm_price == OrdersAItems::IS_ADM_PRICE_YES) ? OrdersAItems::IS_ADM_PRICE_YES : OrdersAItems::IS_ADM_PRICE_NO,
					'is_active' => AItems::IS_ACTIVE,
					'updt' => $now,
					'updt_by' => $req->auth->uid,
				];
				AItems::updt($a_id, $updtAItems);
			}

			$updtOrdersAItems = [
				'ord_id' => $orderAItem[0]->ord_id,
				'ord_code' => $orderAItem[0]->ord_code,
				'flow_type' => $req->flow_type,
				'cash_type' => $req->cash_type,
				'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
				'desc' => $updtAItems['name'],
				'unit_id' => $a_id,
				'unit_type' => $updtAItems['type'],
				'amt_base_flat' => $updtAItems['price'],
				'unit_qty' => $req->a_qty,
				'amt_result_flat' => $updtAItems['price'],
				'amt_total_flat' => $updtAItems['price'] * $req->a_qty,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
			];

			$req->a_invc_price = $req->a_invc_price ?? 0;
			$updtOrdersAItems['amt_bill_base_flat'] = $req->a_invc_price;
			$updtOrdersAItems['amt_bill_result_flat'] = $req->a_invc_price;
			$updtOrdersAItems['amt_bill_total_flat'] = $req->a_invc_price * $req->a_qty;

			$updtOrdersAItems['calc_to_vdr'] = OrdersAItems::CALC_TO_VDR_NO;
			$updtOrdersAItems['v_termin_id'] = 0;
			$updtOrdersAItems['ref_v_termin_id'] = 0;
			if ($req->is_calc_to_vdr == OrdersAItems::CALC_TO_VDR_YES) {
				$updtOrdersAItems['calc_to_vdr'] = OrdersAItems::CALC_TO_VDR_YES;
				$updtOrdersAItems['v_termin_id'] = $orderAItem[0]->v_termin_id;
				$updtOrdersAItems['ref_v_termin_id'] = $orderAItem[0]->ref_v_termin_id;
				if ($orderAItem[0]->calc_to_vdr === OrdersAItems::CALC_TO_VDR_YES) {
					$buy_price = $order[0]->buy_price - $orderAItem[0]->amt_total_flat + $updtOrdersAItems['amt_total_flat'];
					Orders::updateOrder($order[0]->ord_id, [
						'buy_price' => $buy_price,
					]);
				} else {
					$buy_price = $order[0]->buy_price + $updtOrdersAItems['amt_total_flat'];
					Orders::updateOrder($order[0]->ord_id, [
						'buy_price' => $buy_price,
					]);
				}
			} else {
				if ($orderAItem[0]->calc_to_vdr === OrdersAItems::CALC_TO_VDR_YES) {
					$buy_price = $order[0]->buy_price - $orderAItem[0]->amt_total_flat;
					Orders::updateOrder($order[0]->ord_id, [
						'buy_price' => $buy_price,
					]);
				}
			}

			$updtOrdersAItems['invc_to_client'] = OrdersAItems::INVC_TO_CLIENT_NO;
			$updtOrdersAItems['c_termin_id'] = 0;
			$updtOrdersAItems['ref_c_termin_id'] = 0;
			if ($req->is_invc_to_client == OrdersAItems::INVC_TO_CLIENT_YES) {
				$updtOrdersAItems['invc_to_client'] = OrdersAItems::INVC_TO_CLIENT_YES;
				// $updtOrdersAItems['c_termin_id'] = $orderAItem[0]->c_termin_id;
				// $updtOrdersAItems['ref_c_termin_id'] = $orderAItem[0]->ref_c_termin_id;
				if ($orderAItem[0]->c_termin_id === 0) {
					$termins = OrdersTermins::listWithFilter([
						'termin_for' => OrdersTermins::TERMIN_FOR_CLIENT,
						'termin_is_paid' => OrdersTermins::IS_PAID_NO,
						'ord_id' => $order[0]->ord_id,
						'in_stts_merge' => [
							OrdersAItems::STTS_MERGE_NO,
							OrdersAItems::STTS_MERGE_RESULT,
						],
					]);
					$updtOrdersAItems['c_termin_id'] = 0;
					$updtOrdersAItems['ref_c_termin_id'] = 0;
					if (count($termins) > 0) {
						$updtOrdersAItems['c_termin_id'] = $termins[0]->id;
						$updtOrdersAItems['ref_c_termin_id'] = $termins[0]->id;
					}
				} else {
					$updtOrdersAItems['c_termin_id'] = $orderAItem[0]->c_termin_id;
					$updtOrdersAItems['ref_c_termin_id'] = $orderAItem[0]->ref_c_termin_id;
				}
				if ($updtOrdersAItems['c_termin_id'] === 0) {
					DB::rollBack();
					$apiResp = Responses::bad_request('tidak dapat melakukan tagihan ke client, karena semua penagihan sudah close');
					return (new Response($apiResp, $apiResp['meta']['code']));
				}
				if ($orderAItem[0]->invc_to_client === OrdersAItems::INVC_TO_CLIENT_YES) {
					$sell_price = $order[0]->price - $orderAItem[0]->amt_bill_total_flat + $updtOrdersAItems['amt_bill_total_flat'];
					Orders::updateOrder($order[0]->ord_id, [
						'price' => $sell_price,
					]);
				} else {
					$sell_price = $order[0]->price + $updtOrdersAItems['amt_bill_total_flat'];
					Orders::updateOrder($order[0]->ord_id, [
						'price' => $sell_price,
					]);
				}
				Finance::updtChangeInvc($updtOrdersAItems['c_termin_id']);
			} else {
				if ($orderAItem[0]->invc_to_client === OrdersAItems::INVC_TO_CLIENT_YES) {
					$sell_price = $order[0]->price - $orderAItem[0]->amt_bill_total_flat;
					Orders::updateOrder($order[0]->ord_id, [
						'price' => $sell_price,
					]);
					Finance::updtChangeInvc($orderAItem[0]->c_termin_id);
				}
			}

			$updtOrdersAItems['only_client'] = OrdersAItems::ONLY_CLIENT_NO;
			if ($req->only_client == OrdersAItems::ONLY_CLIENT_YES) {
				$updtOrdersAItems['only_client'] = OrdersAItems::ONLY_CLIENT_YES;
			}

			if ($req->is_adm_price == OrdersAItems::IS_ADM_PRICE_YES) {
				$updtOrdersAItems['is_adm_price'] = OrdersAItems::IS_ADM_PRICE_YES;
			} else {
				$updtOrdersAItems['ddln_pay_at'] = $req->ddln_pay_at ?? 0;
				$updtOrdersAItems['ddln_pay_type'] = $req->ddln_pay_type ?? OrdersAItems::DDLN_PAY_TYPE_TIME;
				if ($req->slc_pay_purpose == 'fill' && $req->bank_id) {
					$updtOrdersAItems['bank_id'] = $req->bank_id;
					$updtOrdersAItems['bank_code'] = $req->bank_code;
					$updtOrdersAItems['bank_short_name'] = $req->bank_short;
					$updtOrdersAItems['bank_name'] = $req->bank_name;
					$updtOrdersAItems['bank_acc_name'] = $req->bank_acc_name;
					$updtOrdersAItems['bank_acc_number'] = $req->bank_acc_number;
				}
			}

			if ($req->is_paid == OrdersAItems::IS_PAID_YES) {
				$updtOrdersAItems['is_paid'] = OrdersAItems::IS_PAID_YES;
				$updtOrdersAItems['paid_at'] = $now;
				$updtOrdersAItems['paid_by'] = $req->auth->uid;
			}

			// if ($req->crt_type == OrdersAItems::CRT_TYPE_SYSTEM) {
			// 	$updtOrdersAItems['crt_type'] = OrdersAItems::CRT_TYPE_SYSTEM;
			// } else if ($req->crt_type == OrdersAItems::CRT_TYPE_FINANCE) {
			// 	$updtOrdersAItems['crt_type'] = OrdersAItems::CRT_TYPE_FINANCE;
			// } else {
			// 	$updtOrdersAItems['crt_type'] = OrdersAItems::CRT_TYPE_ADMIN;
			// }

			if ($req->is_adm_price == OrdersAItems::IS_ADM_PRICE_YES) {} else {
				if ($req->submission_proof_base64 && count($req->submission_proof_base64) > 0) {
					foreach ($req->submission_proof_base64 as $i => $img) {
						$clearBase64 = preg_replace('/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/', '', $img);
						$type = 'jpeg';
						if (strpos($img, 'application/pdf') !== false) $type = 'pdf';
						$url_submission_proof_base64[$i] = "orders/" . $orderAItem[0]->ord_id . "/a_items/" . $ord_a_item_id . "/submission/" . $req->auth->uid . "/submission_proof_img_$now" . "_" . "$i.$type";
						if (!Storage::disk('public')->put($url_submission_proof_base64[$i], base64_decode($clearBase64))) {
							DB::rollBack();
							$apiResp = Responses::bad_request('gagal upload bukti pengajuan');
							return (new Response($apiResp, $apiResp['meta']['code']));
						}
					}
				}
			}

			if ($req->is_paid == OrdersAItems::IS_PAID_YES) {
				if ($req->is_paid_proof_base64 && count($req->is_paid_proof_base64) > 0) {
					foreach ($req->is_paid_proof_base64 as $i => $img) {
						$clearBase64 = preg_replace('/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/', '', $img);
						$type = 'jpeg';
						if (strpos($img, 'application/pdf') !== false) $type = 'pdf';
						$url_is_paid_proof_base64[$i] = "orders/" . $orderAItem[0]->ord_id . "/a_items/" . $ord_a_item_id . "/payments/" . $req->auth->uid . "/payments_proof_img_$now" . "_" . "$i.$type";
						if (!Storage::disk('public')->put($url_is_paid_proof_base64[$i], base64_decode($clearBase64))) {
							DB::rollBack();
							$apiResp = Responses::bad_request('gagal upload bukti pembayaran');
							return (new Response($apiResp, $apiResp['meta']['code']));
						}
					}
				}
			}

			if (count($url_submission_proof_base64) > 0) {
				$updtOrdersAItems['img_proof_submission'] = json_encode($url_submission_proof_base64);
			}
			if (count($url_is_paid_proof_base64) > 0) {
				$updtOrdersAItems['img_proof_payment'] = json_encode($url_is_paid_proof_base64);
			}

			OrdersAItems::updt($ord_a_item_id, $updtOrdersAItems);

			$apiResp = Responses::success('success update item');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			if (count($url_submission_proof_base64) > 0) {
				foreach ($url_submission_proof_base64 as $path) {
					Storage::disk('public')->delete($path);
				}
			}
			if (count($url_is_paid_proof_base64) > 0) {
				foreach ($url_is_paid_proof_base64 as $path) {
					Storage::disk('public')->delete($path);
				}
			}
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_del_a_items(Request $req, $ord_a_item_id)
	{
		/**
		 * $req->is_del =>
		 * 	1. delete submission item from admin
		 * 	2. delete item from detail pembayaran menu finance
		 * 	3. delete item from detail penagihan menu finance
		 */
		try {
			$now = time();

			$input = [
				'ord_a_item_id' => $req->ord_a_item_id,
				'is_del' => $req->is_del,
			];
			$rulesInput = [
				'ord_a_item_id' => 'required|integer|not_in:0',
				'is_del' => 'required|integer|not_in:0',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$orderAItem = OrdersAItems::getById($ord_a_item_id);
			if (count($orderAItem) < 1) {
				$apiResp = Responses::not_found('item not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$order = Orders::showOrder([
				'id' => $orderAItem[0]->ord_id,
				// 'get_prefer_type_truck' => 1,
				'get_pic_zone' => 1,
				// 'get_stts_checker' => 1,
				// 'get_checker_data' => 1,
				// 'get_checker_user' => 1,
				// 'get_accidents' => 1,
				'get_client_pt' => 1,
			]);
			if (count($order) < 1) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			if ($req->is_del == 1 || $req->is_del == 2) {
				if ($orderAItem[0]->is_paid == OrdersAItems::IS_PAID_YES) {
					$apiResp = Responses::bad_request('tidak bisa dihapus status pembayaran sudah lunas');
					return (new Response($apiResp, $apiResp['meta']['code']));
				}
			}
			// if $req->is_del == 3
			if ($orderAItem[0]->is_bill_paid == OrdersAItems::IS_PAID_YES) {
				$apiResp = Responses::bad_request('tidak bisa dihapus status penagihan sudah lunas');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			DB::beginTransaction();

			if ($req->is_del == 1 || $req->is_del == 2) {
				$updtOrdersAItems = [
					'dlt' => $now,
					'dlt_by' => $req->auth->uid,
				];
				if ($orderAItem[0]->invc_to_client === OrdersAItems::INVC_TO_CLIENT_YES) {
					$sell_price = $order[0]->price - $orderAItem[0]->amt_bill_total_flat;
					Orders::updateOrder($order[0]->ord_id, [
						'price' => $sell_price,
					]);
					Finance::updtChangeInvc($orderAItem[0]->c_termin_id);
				}
				if ($orderAItem[0]->calc_to_vdr === OrdersAItems::CALC_TO_VDR_YES) {
					$buy_price = $order[0]->buy_price - $orderAItem[0]->amt_total_flat;
					Orders::updateOrder($order[0]->ord_id, [
						'buy_price' => $buy_price,
					]);
				}
				OrdersAItems::updt($ord_a_item_id, $updtOrdersAItems);
			} else if ($req->is_del == 3) {
				if ($orderAItem[0]->calc_to_vdr === OrdersAItems::CALC_TO_VDR_YES) {
					$updtOrdersAItems = [
						'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_NO,
						'updt' => $now,
						'updt_by' => $req->auth->uid,
					];
					$updtOrdersAItems['c_termin_id'] = 0;
					$updtOrdersAItems['ref_c_termin_id'] = 0;
				} else {
					$updtOrdersAItems = [
						'dlt' => $now,
						'dlt_by' => $req->auth->uid,
					];
					$buy_price = $order[0]->buy_price - $orderAItem[0]->amt_total_flat;
					Orders::updateOrder($order[0]->ord_id, [
						'buy_price' => $buy_price,
					]);
				}
				$sell_price = $order[0]->price - $orderAItem[0]->amt_bill_total_flat;
				Orders::updateOrder($order[0]->ord_id, [
					'price' => $sell_price,
				]);
				OrdersAItems::updt($ord_a_item_id, $updtOrdersAItems);
				Finance::updtChangeInvc($orderAItem[0]->c_termin_id);
			}

			$apiResp = Responses::success('success delete item');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_reject_a_items(Request $req, $ord_a_item_id)
	{
		try {
			$now = time();

			$input = [
				'ord_a_item_id' => $ord_a_item_id,
			];
			$rulesInput = [
				'ord_a_item_id' => 'required|integer|not_in:0',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$orderAItem = OrdersAItems::getById($ord_a_item_id);
			if (count($orderAItem) < 1) {
				$apiResp = Responses::not_found('item not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$order = Orders::showOrder([
				'id' => $orderAItem[0]->ord_id,
				// 'get_prefer_type_truck' => 1,
				'get_pic_zone' => 1,
				// 'get_stts_checker' => 1,
				// 'get_checker_data' => 1,
				// 'get_checker_user' => 1,
				// 'get_accidents' => 1,
				'get_client_pt' => 1,
			]);
			if (count($order) < 1) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			if ($orderAItem[0]->is_paid == OrdersAItems::IS_PAID_YES) {
				$apiResp = Responses::bad_request('tidak bisa ditolak status pembayaran sudah lunas');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			if ($orderAItem[0]->is_bill_paid == OrdersAItems::IS_PAID_YES) {
				$apiResp = Responses::bad_request('tidak bisa ditolak status penagihan sudah lunas');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			DB::beginTransaction();

			$updtOrdersAItems = [];

			if ($orderAItem[0]->invc_to_client === OrdersAItems::INVC_TO_CLIENT_YES) {
				$updtOrdersAItems['is_bill_aprv'] = OrdersAItems::IS_APRV_NO;
				$updtOrdersAItems['rjct_bill_at'] = $now;
				$updtOrdersAItems['rjct_bill_by'] = $req->auth->uid;
				$sell_price = $order[0]->price - $orderAItem[0]->amt_bill_total_flat;
				Orders::updateOrder($order[0]->ord_id, [
					'price' => $sell_price,
				]);

				Finance::updtChangeInvc($orderAItem[0]->c_termin_id);
			} else {
				$updtOrdersAItems['c_termin_id'] = 0;
				$updtOrdersAItems['ref_c_termin_id'] = 0;
			}

			if ($orderAItem[0]->calc_to_vdr === OrdersAItems::CALC_TO_VDR_YES) {
				$updtOrdersAItems['is_aprv'] = OrdersAItems::IS_APRV_NO;
				$updtOrdersAItems['rjct_at'] = $now;
				$updtOrdersAItems['rjct_by'] = $req->auth->uid;
				$buy_price = $order[0]->buy_price - $orderAItem[0]->amt_total_flat;
				Orders::updateOrder($order[0]->ord_id, [
					'buy_price' => $buy_price,
				]);
			} else {
				$updtOrdersAItems['v_termin_id'] = 0;
				$updtOrdersAItems['ref_v_termin_id'] = 0;
			}

			OrdersAItems::updt($ord_a_item_id, $updtOrdersAItems);

			$apiResp = Responses::success('success reject item');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	/**
	 * how merger work
	 * pembayaran yang bisa di merge: status lunas/tidak, belum pernah di merge, item additional(not main item)
	 * pembayaran yang tidak bisa di merge: diarsipkan, bekas merge dan selain dari syarat ditas
	 * jangan lupa dikurangin harganya dengan t_orders.buy_price / t_orders.price dan diupdate
	 * buat row t_orders_a_items baru dengan data yang sama, dengan kriteria berikut: 
	 * 		- kecuali t_orders_a_items[ord_code/id,c_termin/v_termin] adalah baru, kolom ref order mereferensi ke item sebelumnya, namun ref termin adalah data baru
	 * 		- crt_type dibuat dari finance, begitupun dengan usernya
	 * 		- is_merge jadi 1, merge_to_a_items_id(item baru dari hasil merge)
	 * jika status pembayaran lunas maka tidak bisa dirubah
	 * setiap ada perubahan di merger yang baru, di arsip pembayaran(order lama,sebelum merger) tidak terubah/terkalulasi jika status pembayaran lunas
	 */
	public function api_finance_merger_a_items(Request $req, $ord_a_item_id)
	{
		try {
			$now = time();

			$input = [
				'ord_a_item_id' => $ord_a_item_id,
				'mrg_to_ord_code' => $req->mrg_to_ord_code,
				'mrg_to_ord_id' => $req->mrg_to_ord_id,
			];
			$rulesInput = [
				'ord_a_item_id' => 'required|integer|not_in:0',
				'mrg_to_ord_code' => 'required|string|min:5',
				'mrg_to_ord_id' => 'nullable|integer|not_in:0',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$mergeFromAItem = OrdersAItems::getById($ord_a_item_id);
			if (count($mergeFromAItem) < 1) {
				$apiResp = Responses::not_found('item not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$mergeFromOrder = Orders::showOrder([
				'id' => $mergeFromAItem[0]->ord_id,
				// 'get_prefer_type_truck' => 1,
				// 'get_pic_zone' => 1,
				// 'get_stts_checker' => 1,
				// 'get_checker_data' => 1,
				// 'get_checker_user' => 1,
				// 'get_accidents' => 1,
				// 'get_client_pt' => 1,
			]);
			if (count($mergeFromOrder) < 1) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$mergeToOrder = Orders::showOrder([
				'code' => $req->mrg_to_ord_code,
				// 'get_prefer_type_truck' => 1,
				// 'get_pic_zone' => 1,
				// 'get_stts_checker' => 1,
				// 'get_checker_data' => 1,
				// 'get_checker_user' => 1,
				// 'get_accidents' => 1,
				// 'get_client_pt' => 1,
			]);
			if (count($mergeToOrder) < 1) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			DB::beginTransaction();

			$updtMergeFromAItems = [
				'is_merge_to' => OrdersAItems::IS_MERGE_YES,
				// 'merge_to_a_id' => 0,
				'merge_to_ord_id' => $mergeToOrder[0]->ord_id,
				'merge_to_ord_code' => $mergeToOrder[0]->ord_code,
				'merge_to_at' => $now,
				'merge_to_by' => $req->auth->uid,
			];
			$insMergeToAItem = [
				'ord_id' => $mergeToOrder[0]->ord_id,
				'ord_code' => $mergeToOrder[0]->ord_code,
				'flow_type' => $mergeFromAItem[0]->flow_type,
				'cash_type' => $mergeFromAItem[0]->cash_type,
				// 'v_termin_id' => $mergeFromAItem[0]->v_termin_id,
				// 'c_termin_id' => $mergeFromAItem[0]->c_termin_id,
				'a_item_type' => $mergeFromAItem[0]->a_item_type,
				'desc' => $mergeFromAItem[0]->desc,
				'unit_id' => $mergeFromAItem[0]->unit_id,
				'unit_type' => $mergeFromAItem[0]->unit_type,
				'unit_qty' => $mergeFromAItem[0]->unit_qty,
				'amt_base_flat' => $mergeFromAItem[0]->amt_base_flat,
				'amt_disc_type' => $mergeFromAItem[0]->amt_disc_type,
				'amt_disc_percent' => $mergeFromAItem[0]->amt_disc_percent,
				'amt_disc_flat' => $mergeFromAItem[0]->amt_disc_flat,
				'amt_result_flat' => $mergeFromAItem[0]->amt_result_flat,
				'amt_total_flat' => $mergeFromAItem[0]->amt_total_flat,
				'ddln_pay_at' => $mergeFromAItem[0]->ddln_pay_at,
				'ddln_pay_type' => $mergeFromAItem[0]->ddln_pay_type,
				'img_proof_submission' => $mergeFromAItem[0]->img_proof_submission,
				'img_proof_payment' => $mergeFromAItem[0]->img_proof_payment,
				'bank_id' => $mergeFromAItem[0]->bank_id,
				'bank_code' => $mergeFromAItem[0]->bank_code,
				'bank_name' => $mergeFromAItem[0]->bank_name,
				'bank_short_name' => $mergeFromAItem[0]->bank_short_name,
				'bank_acc_number' => $mergeFromAItem[0]->bank_acc_number,
				'bank_acc_name' => $mergeFromAItem[0]->bank_acc_name,
				'amt_bill_base_flat' => $mergeFromAItem[0]->amt_bill_base_flat,
				'amt_bill_disc_type' => $mergeFromAItem[0]->amt_bill_disc_type,
				'amt_bill_disc_percent' => $mergeFromAItem[0]->amt_bill_disc_percent,
				'amt_bill_disc_flat' => $mergeFromAItem[0]->amt_bill_disc_flat,
				'amt_bill_result_flat' => $mergeFromAItem[0]->amt_bill_result_flat,
				'amt_bill_total_flat' => $mergeFromAItem[0]->amt_bill_total_flat,
				'invc_to_client' => $mergeFromAItem[0]->invc_to_client,
				'calc_to_vdr' => $mergeFromAItem[0]->calc_to_vdr,
				'is_adm_price' => $mergeFromAItem[0]->is_adm_price,
				'is_paid' => $mergeFromAItem[0]->is_paid,
				'paid_at' => $mergeFromAItem[0]->paid_at,
				'paid_by' => $mergeFromAItem[0]->paid_by,
				'paid_method' => $mergeFromAItem[0]->paid_method,
				'paid_ref_no' => $mergeFromAItem[0]->paid_ref_no,
				'is_bill_paid' => $mergeFromAItem[0]->is_bill_paid,
				'paid_bill_at' => $mergeFromAItem[0]->paid_bill_at,
				'paid_bill_by' => $mergeFromAItem[0]->paid_bill_by,
				'paid_bill_method' => $mergeFromAItem[0]->paid_bill_method,
				'only_client' => $mergeFromAItem[0]->only_client,
				'only_vdr' => $mergeFromAItem[0]->only_vdr,
				'is_hidden' => $mergeFromAItem[0]->is_hidden,
				'is_tax' => $mergeFromAItem[0]->is_tax,
				'is_disc' => $mergeFromAItem[0]->is_disc,
				'is_aprv' => $mergeFromAItem[0]->is_aprv,
				'rjct_at' => $mergeFromAItem[0]->rjct_at,
				'rjct_by' => $mergeFromAItem[0]->rjct_by,
				'is_bill_aprv' => $mergeFromAItem[0]->is_bill_aprv,
				'rjct_bill_at' => $mergeFromAItem[0]->rjct_bill_at,
				'rjct_bill_by' => $mergeFromAItem[0]->rjct_bill_by,
				'is_merge_from' => OrdersAItems::IS_MERGE_YES,
				'merge_from_a_id' => $mergeFromAItem[0]->id,
				'merge_from_ord_id' => $mergeFromAItem[0]->ord_id,
				'merge_from_ord_code' => $mergeFromAItem[0]->ord_code,
				'merge_from_at' => $now,
				'merge_from_by' => $req->auth->uid,
				'ref_ord_id' => $mergeFromAItem[0]->ord_id,
				'ref_ord_code' => $mergeFromAItem[0]->ord_code,
				// 'ref_v_termin_id' => $mergeFromAItem[0]->v_termin_id,
				// 'ref_c_termin_id' => $mergeFromAItem[0]->c_termin_id,
				'ref_ord_a_item_id' => $mergeFromAItem[0]->id,
				'crt' => $now,
				'crt_by' => $req->auth->uid,
				'crt_type' => OrdersAItems::CRT_TYPE_FINANCE,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
			];

			if ($insMergeToAItem['invc_to_client'] === OrdersAItems::INVC_TO_CLIENT_YES) {
				$termins = OrdersTermins::listWithFilter([
					'termin_for' => OrdersTermins::TERMIN_FOR_CLIENT,
					'termin_is_paid' => OrdersTermins::IS_PAID_NO,
					'ord_id' => $mergeToOrder[0]->ord_id,
					'in_stts_merge' => [
						OrdersAItems::STTS_MERGE_NO,
						OrdersAItems::STTS_MERGE_RESULT,
					],
				]);
				$insMergeToAItem['c_termin_id'] = 0;
				$insMergeToAItem['ref_c_termin_id'] = 0;
				if (count($termins) > 0) {
					$insMergeToAItem['c_termin_id'] = $termins[0]->id;
					$insMergeToAItem['ref_c_termin_id'] = $termins[0]->id;
				}
				if ($insMergeToAItem['c_termin_id'] === 0) {
					DB::rollBack();
					$apiResp = Responses::bad_request('tidak dapat melakukan merge ke transaksi yang dituju, karena semua penagihan ke client sudah close');
					return (new Response($apiResp, $apiResp['meta']['code']));
				}

				$sell_price = $mergeToOrder[0]->price + $insMergeToAItem['amt_bill_total_flat'];
				Orders::updateOrder($mergeToOrder[0]->ord_id, [
					'price' => $sell_price,
				]);

				Finance::updtChangeInvc($insMergeToAItem['c_termin_id']);
			} else {
				$insMergeToAItem['c_termin_id'] = 0;
				$insMergeToAItem['ref_c_termin_id'] = 0;
			}

			if ($insMergeToAItem['calc_to_vdr'] === OrdersAItems::CALC_TO_VDR_YES) {
				$termins = OrdersTermins::listWithFilter([
					'ord_id' => $mergeToOrder[0]->ord_id,
					'termin_for' => OrdersTermins::TERMIN_FOR_VENDOR,
					'termin_is_paid' => OrdersTermins::IS_PAID_NO,
					'in_stts_merge' => [
						OrdersAItems::STTS_MERGE_NO,
						OrdersAItems::STTS_MERGE_RESULT,
					],
				]);
				$insMergeToAItem['v_termin_id'] = 0;
				$insMergeToAItem['ref_v_termin_id'] = 0;
				if (count($termins) > 0) {
					$insMergeToAItem['v_termin_id'] = $termins[0]->id;
					$insMergeToAItem['ref_v_termin_id'] = $termins[0]->id;
				}
				if ($insMergeToAItem['v_termin_id'] === 0) {
					$termins = OrdersTermins::listWithFilter([
						'ord_id' => $mergeToOrder[0]->ord_id,
						'termin_for' => OrdersTermins::TERMIN_FOR_VENDOR,
						'in_stts_merge' => [
							OrdersAItems::STTS_MERGE_NO,
							OrdersAItems::STTS_MERGE_RESULT,
						],
					]);
					$insMergeToAItem['v_termin_id'] = $termins[count($termins) - 1]->id;
					$insMergeToAItem['ref_v_termin_id'] = $termins[count($termins) - 1]->id;
				}

				$buy_price = $mergeToOrder[0]->buy_price + $insMergeToAItem['amt_total_flat'];
				Orders::updateOrder($mergeToOrder[0]->ord_id, [
					'buy_price' => $buy_price,
				]);
			} else {
				$insMergeToAItem['v_termin_id'] = 0;
				$insMergeToAItem['ref_v_termin_id'] = 0;
			}

			$aid = OrdersAItems::add($insMergeToAItem);
			$insMergeToAItem['id'] = $aid;
			$updtMergeFromAItems['merge_to_a_id'] = $aid;
			OrdersAItems::updt($ord_a_item_id, $updtMergeFromAItems);

			$apiResp = Responses::success('success merge item');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	/**
	 * merge ada 2 termin dari 1 trx ? jadi 1 termin
	 * merge ada 4 termin dari 2 trx ? masing2 jadi 1 termin
	 * merge kalau sudah ada adt items ? hanya termin yang di recreate, adt items tidak direcreate
	 * merge kalau ada yang sudah lunas baik main item / adt item ? gabisa
	 * saat recreate termin sisanya ngikut termin sebelumnya, saat ini belum ada diskon
	 */
	public function api_finance_merger_trx(Request $req)
	{
		try {
			$now = time();

			$input = [
				'mrg_from_ord_code' => $req->mrg_from_ord_code,
				'mrg_from_ord_id' => $req->mrg_from_ord_id,
				'mrg_to_ord_code' => $req->mrg_to_ord_code,
				'mrg_to_ord_id' => $req->mrg_to_ord_id,
				'new_buy_price' => $req->new_buy_price,
				'note' => $req->note,
			];
			$rulesInput = [
				'mrg_from_ord_code' => 'required|string|min:5',
				'mrg_from_ord_id' => 'nullable|integer|not_in:0',
				'mrg_to_ord_code' => 'required|string|min:5',
				'mrg_to_ord_id' => 'nullable|integer|not_in:0',
				'new_buy_price' => 'required|numeric|not_in:0',
				'note' => 'nullable|string',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			if ($req->mrg_from_ord_code == $req->mrg_to_ord_code) {
				$apiResp = Responses::bad_input('tidak dapat merger pada transaksi yang  sama');
				return (new Response($apiResp, $apiResp['meta']['code']));	
			}

			$mrgFromOrd = Orders::showOrder([
				'code' => $req->mrg_from_ord_code,
				'get_zone_zonasi' => 1,
				'get_vdr_bank' => 1,
				// 'get_prefer_type_truck' => 1,
				// 'get_pic_zone' => 1,
				// 'get_client_pt' => 1,
			]);
			if (count($mrgFromOrd) < 1) {
				$apiResp = Responses::not_found('order code not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			$mrgToOrd = Orders::showOrder([
				'code' => $req->mrg_to_ord_code,
				'get_zone_zonasi' => 1,
				'get_vdr_bank' => 1,
				// 'get_prefer_type_truck' => 1,
				// 'get_pic_zone' => 1,
				// 'get_client_pt' => 1,
			]);
			if (count($mrgToOrd) < 1) {
				$apiResp = Responses::not_found('order code not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			if ($mrgFromOrd[0]->vdr_id !== $mrgToOrd[0]->vdr_id) {
				$apiResp = Responses::bad_request('merge hanya berlaku untuk vendor yang sama dikedua transaksi');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			if ($mrgFromOrd[0]->vhc_id !== $mrgToOrd[0]->vhc_id) {
				$apiResp = Responses::bad_request('merge hanya berlaku untuk kendaraan yang sama dikedua transaksi');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			if ($mrgFromOrd[0]->drv_id !== $mrgToOrd[0]->drv_id) {
				$apiResp = Responses::bad_request('merge hanya berlaku untuk pengemudi yang sama dikedua transaksi');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			// if ($req->new_buy_price > $mrgFromOrd[0]->price) {
			// 	$apiResp = Responses::bad_request('biaya melebihi harga jual pada transaksi ' . $mrgFromOrd[0]->ord_code);
			// 	return (new Response($apiResp, $apiResp['meta']['code']));
			// }
			// if ($req->new_buy_price > $mrgToOrd[0]->price) {
			// 	$apiResp = Responses::bad_request('biaya melebihi harga jual pada transaksi ' . $mrgToOrd[0]->ord_code);
			// 	return (new Response($apiResp, $apiResp['meta']['code']));
			// }

			$updtBuyPriceFrom = 0;
			$updtBuyPriceTo = 0;

			// pengurangan update buy price dari termin
			$allTerminsVdrFrom = OrdersTermins::listWithFilter([
				'ord_id' => $mrgFromOrd[0]->ord_id,
				'termin_for' => OrdersTermins::TERMIN_FOR_VENDOR,
				'in_stts_merge' => [
					OrdersAItems::STTS_MERGE_NO,
					OrdersAItems::STTS_MERGE_RESULT,
				],
			]);
			$tvids1 = [];
			$totTerminV1 = 0;
			foreach ($allTerminsVdrFrom as $terminVdr1) {
				$updtBuyPriceFrom -= $terminVdr1->termin_result_flat;
				if ($terminVdr1->termin_is_paid === OrdersTermins::IS_PAID_YES) {
					$apiResp = Responses::bad_request('tidak dapat merger, ada item yang sudah terbayar pada transaksi ' . $mrgFromOrd[0]->ord_code);
					return (new Response($apiResp, $apiResp['meta']['code']));	
				}
				$tvids1[] = $terminVdr1->id;
				$totTerminV1 += $terminVdr1->termin_result_flat;
			}
			$allTerminsVdrTo = OrdersTermins::listWithFilter([
				'ord_id' => $mrgToOrd[0]->ord_id,
				'termin_for' => OrdersTermins::TERMIN_FOR_VENDOR,
				'in_stts_merge' => [
					OrdersAItems::STTS_MERGE_NO,
					OrdersAItems::STTS_MERGE_RESULT,
				],
			]);
			$tvids2 = [];
			$totTerminV2 = 0;
			foreach ($allTerminsVdrTo as $terminVdr2) {
				$updtBuyPriceTo -= $terminVdr2->termin_result_flat;
				if ($terminVdr2->termin_is_paid === OrdersTermins::IS_PAID_YES) {
					$apiResp = Responses::bad_request('tidak dapat merger, ada item yang sudah terbayar pada order code ' . $mrgToOrd[0]->ord_code);
					return (new Response($apiResp, $apiResp['meta']['code']));	
				}
				$tvids2[] = $terminVdr2->id;
				$totTerminV2 += $terminVdr2->termin_result_flat;
			}

			$pembagi = $totTerminV1 + $totTerminV2;
			$newTerminBuyPriceFrom = round($totTerminV1 / $pembagi * $req->new_buy_price);
			$newTerminBuyPriceTo = round($totTerminV2 / $pembagi * $req->new_buy_price);
			// round(2000/6000*5000); // 1666.6666666666665 -> round -> 1667.0

			// penambahan update buy price dari buy_price sebelumnya(termasuk adt items) dan new termin, jadi tidak perlu kalkulasi ulang a_items
			$updtBuyPriceFrom += $mrgFromOrd[0]->buy_price + $newTerminBuyPriceFrom;
			$updtBuyPriceTo += $mrgToOrd[0]->buy_price + $newTerminBuyPriceTo;

			// get orders_a_items main_item with that termin
			$mainItems1 = OrdersAItems::showAItemByVids($tvids1, ['a_item_type' => OrdersAItems::A_TYPE_PRIMARY]);
			$mainItems2 = OrdersAItems::showAItemByVids($tvids2, ['a_item_type' => OrdersAItems::A_TYPE_PRIMARY]);

			$nanoid = new Nanoid();
			$merge_code = $nanoid->formattedId('0123456789', 9);
			// $merge_code = $now;
			$doWhile = true;
			do {
				if (substr($merge_code, 0, 1) == 0) {
					$merge_code = $nanoid->formattedId('0123456789', 9);
				} else {
					$doWhile = false;
				}
			} while ($doWhile);

			DB::beginTransaction();

			// new termin1 utk transaksi 1
			$v1_termin1_percent = 100;
			$v1_termin1_calc_percent = $v1_termin1_percent / 100 * $newTerminBuyPriceFrom;
			$insTermin1From = [
				'ord_id' => $mrgFromOrd[0]->ord_id,
				'ord_code' => $mrgFromOrd[0]->ord_code,
				'flow_type' => OrdersTermins::FLOW_TYPE_PAYMENT,
				'cash_type' => OrdersTermins::TYPE_CASH_OUT,
				'sequence' => count($allTerminsVdrFrom) + 1,
				'termin_base_flat' => $newTerminBuyPriceFrom,
				'termin_amt_type' => OrdersTermins::AMT_TYPE_PERCENT,
				'termin_amt' => $v1_termin1_percent,
				'termin_calc_percent' => $v1_termin1_calc_percent,
				'termin_result_flat' => $v1_termin1_calc_percent,
				'termin_ddln_type' => $allTerminsVdrFrom[0]->termin_ddln_type,
				'termin_ddln_at' => $allTerminsVdrFrom[0]->termin_ddln_at,
				'termin_for' => OrdersTermins::TERMIN_FOR_VENDOR,
				'is_active' => OrdersTermins::IS_ACTIVE_YES,
				'stts_merge' => OrdersTermins::STTS_MERGE_RESULT,
				'group_merge_code' => $merge_code,
				'merge_at' => $now,
				'crt' => $now,
				'crt_by' => $req->auth->uid,
				'crt_type' => OrdersTermins::CRT_TYPE_ADMIN,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
			];
			$v1_termin1_id = OrdersTermins::add($insTermin1From);
			$unit_qty = 1;
			$ddln_pay_type = ($insTermin1From['termin_ddln_at'] === OrdersTermins::DDLN_TERMIN_TYPE_TIME) ? OrdersAItems::DDLN_PAY_TYPE_TIME : OrdersAItems::DDLN_PAY_TYPE_ORD_FINISH;
			OrdersAItems::add([
				'ord_id' => $mrgFromOrd[0]->ord_id,
				'ord_code' => $mrgFromOrd[0]->ord_code,
				'flow_type' => OrdersAItems::FLOW_TYPE_PAYMENT,
				'cash_type' => OrdersAItems::TYPE_CASH_OUT,
				'v_termin_id' => $v1_termin1_id,
				'a_item_type' => OrdersAItems::A_TYPE_PRIMARY,
				'desc' => "Pengantaran Logistik<br>" . ucwords(strtolower($mrgFromOrd[0]->pck_prid_name)) . " - " . ucwords(strtolower($mrgFromOrd[0]->drop_prid_name)) . "<br>" . date('d F Y', $mrgFromOrd[0]->set_pck_at) . " WIB<br>Pembayaran termin 1",
				'unit_id' => 0,
				'unit_type' => UnitTypes::UNIT_TYPE_PAKET,
				'unit_qty' => $unit_qty,
				'amt_base_flat' => $insTermin1From['termin_result_flat'],
				'amt_result_flat' => $insTermin1From['termin_result_flat'],
				'amt_total_flat' => $insTermin1From['termin_result_flat'] * $unit_qty,
				'ddln_pay_at' => $insTermin1From['termin_ddln_at'],
				'ddln_pay_type' => $ddln_pay_type,
				'img_proof_submission' => null,
				'img_proof_payment' => null,
				'bank_id' => $mrgFromOrd[0]->vdr_bank_id,
				'bank_code' => $mrgFromOrd[0]->vdr_bank_code,
				'bank_name' => $mrgFromOrd[0]->vdr_bank_name,
				'bank_short_name' => $mrgFromOrd[0]->vdr_bank_short_name,
				'bank_acc_number' => $mrgFromOrd[0]->vdr_bank_acc_number,
				'bank_acc_name' => $mrgFromOrd[0]->vdr_bank_acc_name,
				'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_NO,
				'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_YES,
				'only_vdr' => OrdersAItems::ONLY_VDR_YES,
				'is_active' => OrdersAItems::IS_ACTIVE_YES,
				'stts_merge' => OrdersAItems::STTS_MERGE_RESULT,
				'group_merge_code' => $merge_code,
				'merge_at' => $now,
				'ref_ord_id' => $mrgFromOrd[0]->ord_id,
				'ref_ord_code' => $mrgFromOrd[0]->ord_code,
				'ref_v_termin_id' => $v1_termin1_id,
				'crt' => $now,
				'crt_by' => $req->auth->uid,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
			]);

			// new termin1 utk transaksi 2
			$v2_termin1_percent = 100;
			$v2_termin1_calc_percent = $v2_termin1_percent / 100 * $newTerminBuyPriceTo;
			$insTermin1To = [
				'ord_id' => $mrgToOrd[0]->ord_id,
				'ord_code' => $mrgToOrd[0]->ord_code,
				'flow_type' => OrdersTermins::FLOW_TYPE_PAYMENT,
				'cash_type' => OrdersTermins::TYPE_CASH_OUT,
				'sequence' => count($allTerminsVdrTo) + 1,
				'termin_base_flat' => $newTerminBuyPriceTo,
				'termin_amt_type' => OrdersTermins::AMT_TYPE_PERCENT,
				'termin_amt' => $v2_termin1_percent,
				'termin_calc_percent' => $v2_termin1_calc_percent,
				'termin_result_flat' => $v2_termin1_calc_percent,
				'termin_ddln_type' => $allTerminsVdrTo[0]->termin_ddln_type,
				'termin_ddln_at' => $allTerminsVdrTo[0]->termin_ddln_at,
				'termin_for' => OrdersTermins::TERMIN_FOR_VENDOR,
				'is_active' => OrdersTermins::IS_ACTIVE_YES,
				'stts_merge' => OrdersTermins::STTS_MERGE_RESULT,
				'group_merge_code' => $merge_code,
				'merge_at' => $now,
				'crt' => $now,
				'crt_by' => $req->auth->uid,
				'crt_type' => OrdersTermins::CRT_TYPE_ADMIN,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
			];
			$v2_termin1_id = OrdersTermins::add($insTermin1To);
			$unit_qty = 1;
			$ddln_pay_type = ($insTermin1To['termin_ddln_at'] === OrdersTermins::DDLN_TERMIN_TYPE_TIME) ? OrdersAItems::DDLN_PAY_TYPE_TIME : OrdersAItems::DDLN_PAY_TYPE_ORD_FINISH;
			OrdersAItems::add([
				'ord_id' => $mrgToOrd[0]->ord_id,
				'ord_code' => $mrgToOrd[0]->ord_code,
				'flow_type' => OrdersAItems::FLOW_TYPE_PAYMENT,
				'cash_type' => OrdersAItems::TYPE_CASH_OUT,
				'v_termin_id' => $v2_termin1_id,
				'a_item_type' => OrdersAItems::A_TYPE_PRIMARY,
				'desc' => "Pengantaran Logistik<br>" . ucwords(strtolower($mrgToOrd[0]->pck_prid_name)) . " - " . ucwords(strtolower($mrgToOrd[0]->drop_prid_name)) . "<br>" . date('d F Y', $mrgToOrd[0]->set_pck_at) . " WIB<br>Pembayaran termin 1",
				'unit_id' => 0,
				'unit_type' => UnitTypes::UNIT_TYPE_PAKET,
				'unit_qty' => $unit_qty,
				'amt_base_flat' => $insTermin1To['termin_result_flat'],
				'amt_result_flat' => $insTermin1To['termin_result_flat'],
				'amt_total_flat' => $insTermin1To['termin_result_flat'] * $unit_qty,
				'ddln_pay_at' => $insTermin1To['termin_ddln_at'],
				'ddln_pay_type' => $ddln_pay_type,
				'img_proof_submission' => null,
				'img_proof_payment' => null,
				'bank_id' => $mrgToOrd[0]->vdr_bank_id,
				'bank_code' => $mrgToOrd[0]->vdr_bank_code,
				'bank_name' => $mrgToOrd[0]->vdr_bank_name,
				'bank_short_name' => $mrgToOrd[0]->vdr_bank_short_name,
				'bank_acc_number' => $mrgToOrd[0]->vdr_bank_acc_number,
				'bank_acc_name' => $mrgToOrd[0]->vdr_bank_acc_name,
				'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_NO,
				'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_YES,
				'only_vdr' => OrdersAItems::ONLY_VDR_YES,
				'is_active' => OrdersAItems::IS_ACTIVE_YES,
				'stts_merge' => OrdersAItems::STTS_MERGE_RESULT,
				'group_merge_code' => $merge_code,
				'merge_at' => $now,
				'ref_ord_id' => $mrgToOrd[0]->ord_id,
				'ref_ord_code' => $mrgToOrd[0]->ord_code,
				'ref_v_termin_id' => $v2_termin1_id,
				'crt' => $now,
				'crt_by' => $req->auth->uid,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
			]);

			foreach ($allTerminsVdrFrom as $terminVdr1) {
				if ($terminVdr1->termin_is_paid !== OrdersTermins::IS_PAID_YES) {
					OrdersTermins::updt($terminVdr1->id, [
						'is_active' => OrdersTermins::IS_ACTIVE_NO,
						'stts_merge' => OrdersTermins::STTS_MERGE_TO,
						'merge_to_code' => $merge_code,
						'merge_at' => $now,
					]);
				}
			}
			foreach ($allTerminsVdrTo as $terminVdr2) {
				if ($terminVdr2->termin_is_paid !== OrdersTermins::IS_PAID_YES) {
					OrdersTermins::updt($terminVdr2->id, [
						'is_active' => OrdersTermins::IS_ACTIVE_NO,
						'stts_merge' => OrdersTermins::STTS_MERGE_TO,
						'merge_to_code' => $merge_code,
						'merge_at' => $now,
					]);
				}
			}

			foreach ($mainItems1 as $main1) {
				OrdersAItems::updt($main1->ord_a_item_id, [
					'is_active' => OrdersTermins::IS_ACTIVE_NO,
					'stts_merge' => OrdersTermins::STTS_MERGE_TO,
					'merge_to_code' => $merge_code,
					'merge_at' => $now,
				]);
			}
			foreach ($mainItems2 as $main2) {
				OrdersAItems::updt($main2->ord_a_item_id, [
					'is_active' => OrdersTermins::IS_ACTIVE_NO,
					'stts_merge' => OrdersTermins::STTS_MERGE_TO,
					'merge_to_code' => $merge_code,
					'merge_at' => $now,
				]);
			}

			Orders::updateOrder($mrgFromOrd[0]->ord_id, [
				'buy_price' => $updtBuyPriceFrom,
				'group_code' => $merge_code,
				'stts_merge' => Orders::STTS_MERGE_RESULT,
				'group_merge_code' => $merge_code,
				'merge_at' => $now,
				'merge_note' => $req->note,
			]);
			Orders::updateOrder($mrgToOrd[0]->ord_id, [
				'buy_price' => $updtBuyPriceTo,
				'group_code' => $merge_code,
				'stts_merge' => Orders::STTS_MERGE_RESULT,
				'group_merge_code' => $merge_code,
				'merge_at' => $now,
				'merge_note' => $req->note,
			]);

			$apiResp = Responses::success('success merge transaksi');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	// 
	/**
	 * diskon disini defaultnya minus, jadi jangan dikurangin nanti malah jadi +
	 * ppn dan pph jika type pajak sudah termasuk pajak maka mendjadi minus
	 */
	public function api_finance_crt_updt_invc(Request $req)
	{
		$url_up_paid_proof_base64 = [];
		try {
			$now = time();

			$input = [
				'ord_id' => $req->ord_id,
				'ord_code' => $req->ord_code,
				'termin_id' => $req->termin_id,
				'items' => $req->items,
				'subtotal' => $req->subtotal,
				'tax_type' => $req->tax_type,
				'tax_type_kind' => $req->tax_type_kind,
				'ppn_percent' => $req->ppn_percent,
				'ppn_flat' => $req->ppn_flat,
				'pph_percent' => $req->pph_percent,
				'pph_flat' => $req->pph_flat,
				'tax_flat' => $req->tax_flat,
				'disc_type' => $req->disc_type,
				'disc_percent' => $req->disc_percent,
				'disc_flat' => $req->disc_flat,
				'total' => $req->total,
				'is_gnrt_invc' => $req->is_gnrt_invc,
			];
			$rulesInput = [
				'ord_id' => 'required|integer|not_in:0',
				'ord_code' => 'required|string',
				'termin_id' => 'required|integer|not_in:0',
				'items' => 'required|string',
				'subtotal' => 'required|numeric',
				'tax_type' => 'required|numeric',
				'tax_type_kind' => 'required|numeric',
				'ppn_percent' => 'required|numeric',
				'ppn_flat' => 'required|numeric',
				'pph_percent' => 'required|numeric',
				'pph_flat' => 'required|numeric',
				'tax_flat' => 'required|numeric',
				'disc_type' => 'required|numeric',
				'disc_percent' => 'required|numeric',
				'disc_flat' => 'required|numeric',
				'total' => 'required|numeric',
				'is_gnrt_invc' => 'nullable|integer|not_in:0',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			if (strpos($req->items, ',') !== false) {
				$req->items = substr($req->items, 0, -1);
			}

			$order = Orders::showOrder([
				'id' => $req->ord_id,
				'get_client_pt' => 1,
			]);
			if (count($order) < 1 || $order === false) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			$ord_invc = OrdersInvoices::getByTerminId($req->termin_id);
			$is_updt = true;
			if (count($ord_invc) < 1 || $ord_invc === false) {
				$is_updt = false;
				$code = Helper::gnrtInvcCode($order[0]->ord_code);
				// $nanoid = new Nanoid();
				// $code = $nanoid->formattedId('0123456789', 12);
				// $doWhile = true;
				// do {
				// 	$uniqCode = OrdersInvoices::getByCode($code);
				// 	if (count($uniqCode) > 0) {
				// 		$code = $nanoid->formattedId('0123456789', 12);
				// 	} else {
				// 		$doWhile = false;
				// 	}
				// } while ($doWhile);
			} else {
				$invc_id = $ord_invc[0]->id;
				$code = $ord_invc[0]->code;
				if ($req->is_gnrt_invc == OrdersInvoices::IS_GNRT_INVC_YES) {
					// $is_gnrt_invc = OrdersInvoices::IS_GNRT_INVC_YES;
					// $code = Helper::gnrtInvcCode($order[0]->ord_code);
				}
				// else if ($ord_invc[0]->is_gnrt_invc == OrdersInvoices::IS_GNRT_INVC_YES) {
				// 	$is_gnrt_invc = OrdersInvoices::IS_GNRT_INVC_YES;
				// } else {
				// 	$is_gnrt_invc = OrdersInvoices::IS_GNRT_INVC_NO;
				// }
			}

			$a_item_ppn = OrdersAItems::listAItems([
				'c_termin_id' => $req->termin_id,
				'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
				'is_tax' => OrdersAItems::IS_TAX_YES,
				'is_ppn' => OrdersAItems::IS_TAX_YES,
			]);

			$a_item_pph = OrdersAItems::listAItems([
				'c_termin_id' => $req->termin_id,
				'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
				'is_tax' => OrdersAItems::IS_TAX_YES,
				'is_pph' => OrdersAItems::IS_TAX_YES,
			]);

			$a_item_disc = OrdersAItems::listAItems([
				'c_termin_id' => $req->termin_id,
				'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
				'is_disc' => OrdersAItems::IS_DISC_YES,
			]);

			$req->tax_flat = round($req->tax_flat);
			$req->disc_flat = round($req->disc_flat);

			DB::beginTransaction();

			$sell_price = $order[0]->price;

			$old_bill_items = OrdersAItems::showAItemByIds(explode(',', $req->items));
			$perbedaan_selisih = 0;
			foreach ($old_bill_items as $i => $bill_item) {
				if ($req->tax_type_kind == OrdersAItems::AMT_TAX_TYPE_INCLUDE) {
					$before_ppn = round($bill_item->amt_bill_base_flat / OrdersAItems::PPN_PERCENT_INCLUDE);
					$ppn = round($bill_item->amt_bill_base_flat - $before_ppn);
					$amt_bill_base_tax_flat = round($before_ppn);
					$amt_bill_total_flat = round($amt_bill_base_tax_flat * $bill_item->unit_qty);
					OrdersAItems::updt($bill_item->id, [
						'amt_bill_tax_type' => $req->tax_type_kind,
						'amt_bill_tax_ppn_percent' => $req->ppn_percent,
						'amt_bill_tax_ppn_flat' => $ppn,
						'amt_bill_tax_pph_percent' => $req->pph_percent,
						'amt_bill_tax_pph_flat' => 0,
						'amt_bill_total_tax_flat' => $amt_bill_base_tax_flat,
						'amt_bill_result_flat' => $amt_bill_base_tax_flat,
						'amt_bill_total_flat' => $amt_bill_total_flat,
					]);
					$sell_price = round($sell_price + $bill_item->amt_bill_total_flat);
					$sell_price = round($sell_price - $amt_bill_total_flat);
					$perbedaan_selisih += round($bill_item->amt_bill_total_flat - $amt_bill_total_flat);
				} else {
					OrdersAItems::updt($bill_item->id, [
						'amt_bill_tax_type' => 0,
						'amt_bill_tax_ppn_percent' => 0,
						'amt_bill_tax_ppn_flat' => 0,
						'amt_bill_tax_pph_percent' => 0,
						'amt_bill_tax_pph_flat' => 0,
						'amt_bill_total_tax_flat' => 0,
						'amt_bill_result_flat' => round($bill_item->amt_bill_base_flat),
						'amt_bill_total_flat' => round($bill_item->amt_bill_base_flat * $bill_item->unit_qty),
					]);
					$sell_price = round($sell_price - $bill_item->amt_bill_total_flat);
					$sell_price = round($sell_price + $bill_item->amt_bill_base_flat * $bill_item->unit_qty);
				}
			}
			$sell_price = $sell_price - $perbedaan_selisih;

			$a_item_ppn_id = 0;
			$a_item_pph_id = 0;

			/**
			 * KALAU SUDAH TERMASUK PAJAK YANG DIHITUNG DI SUMMARY (PENGHASILANNYA) YANG 1.5
			 * KALAU BELUM TERMASUK PAJAK YANG DIHITUNG DI SUMMARY (PENGHASILANNYA) YANG 1.5 + PAJAK
			 */

			// dump('sell_price => '. $sell_price);
			if ($req->tax_type_kind == OrdersAItems::AMT_TAX_TYPE_INCLUDE) {
				if ($a_item_ppn === false || count($a_item_ppn) < 1) {
					$insPpn = [
						'ord_id' => $order[0]->ord_id,
						'ord_code' => $order[0]->ord_code,
						'c_termin_id' => $req->termin_id,
						'flow_type' => OrdersInvoices::FLOW_TYPE_BILLING,
						'cash_type' => OrdersInvoices::TYPE_CASH_IN,
						'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
						'desc' => "PPN ($req->ppn_percent%)",
						'unit_id' => 0,
						'unit_type' => UnitTypes::UNIT_TYPE_PCS,
						'amt_bill_base_flat' => $req->ppn_flat,
						'unit_qty' => 1,
						'amt_bill_tax_type' => $req->tax_type_kind,
						'amt_bill_result_flat' => $req->ppn_flat,
						'amt_bill_total_flat' => $req->ppn_flat,
						'ddln_pay_at' => 0,
						'ddln_pay_type' => OrdersAItems::DDLN_PAY_TYPE_TIME,
						'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_YES,
						'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_NO,
						'is_adm_price' => OrdersAItems::IS_ADM_PRICE_NO,
						'only_client' => OrdersAItems::ONLY_CLIENT_YES,
						'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
						'is_tax' => OrdersAItems::IS_TAX_YES,
						'is_tax_type' => $req->tax_type_kind,
						'is_ppn' => OrdersAItems::IS_TAX_YES,
						'ref_ord_id' => $order[0]->ord_id,
						'ref_ord_code' => $order[0]->ord_code,
						'ref_c_termin_id' => $req->termin_id,
						'crt' => $now,
						'crt_by' => $req->auth->uid,
						'updt' => $now,
						'updt_by' => $req->auth->uid,
					];
					$a_item_ppn_id = OrdersAItems::add($insPpn);
					// $sell_price = $sell_price + $insPpn['amt_bill_total_flat']; // +
				} else {
					$a_item_ppn_id = $a_item_ppn[0]->id;
					$updtPpn = [
						'desc' => "PPN ($req->ppn_percent%)",
						'unit_id' => 0,
						'unit_type' => UnitTypes::UNIT_TYPE_PCS,
						'amt_bill_base_flat' => $req->ppn_flat,
						'unit_qty' => 1,
						'amt_bill_result_flat' => $req->ppn_flat,
						'amt_bill_total_flat' => $req->ppn_flat,
						'is_tax_type' => $req->tax_type_kind,
						'updt' => $now,
						'updt_by' => $req->auth->uid,
					];
					OrdersAItems::updt($a_item_ppn[0]->id, $updtPpn);
					// if ($updtPpn['amt_bill_total_flat'] != $a_item_ppn[0]->amt_bill_total_flat) {
					// 	$sell_price = $sell_price - $a_item_ppn[0]->amt_bill_total_flat + $updtPpn['amt_bill_total_flat']; // - +
					// }
					if ($updtPpn['amt_bill_total_flat'] != $a_item_ppn[0]->amt_bill_total_flat) {
						// $sell_price = $sell_price - $a_item_ppn[0]->amt_bill_total_flat + $updtPpn['amt_bill_total_flat']; // - +
					}
				}

				if ($a_item_pph === false || count($a_item_pph) < 1) {
					// $insPph = [
					// 	'ord_id' => $order[0]->ord_id,
					// 	'ord_code' => $order[0]->ord_code,
					// 	'c_termin_id' => $req->termin_id,
					// 	'flow_type' => OrdersInvoices::FLOW_TYPE_BILLING,
					// 	'cash_type' => OrdersInvoices::TYPE_CASH_IN,
					// 	'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
					// 	'desc' => "PPH ($req->pph_percent%)",
					// 	'unit_id' => 0,
					// 	'unit_type' => UnitTypes::UNIT_TYPE_PCS,
					// 	'amt_bill_base_flat' => $req->pph_flat,
					// 	'unit_qty' => 1,
					// 	'amt_bill_tax_type' => $req->tax_type_kind,
					// 	'amt_bill_result_flat' => $req->pph_flat,
					// 	'amt_bill_total_flat' => $req->pph_flat,
					// 	'ddln_pay_at' => 0,
					// 	'ddln_pay_type' => OrdersAItems::DDLN_PAY_TYPE_TIME,
					// 	'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_YES,
					// 	'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_NO,
					// 	'is_adm_price' => OrdersAItems::IS_ADM_PRICE_NO,
					// 	'only_client' => OrdersAItems::ONLY_CLIENT_YES,
					// 	'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
					// 	'is_tax' => OrdersAItems::IS_TAX_YES,
					// 	'is_tax_type' => $req->tax_type_kind,
					// 	'is_pph' => OrdersAItems::IS_TAX_YES,
					// 	'ref_ord_id' => $order[0]->ord_id,
					// 	'ref_ord_code' => $order[0]->ord_code,
					// 	'ref_c_termin_id' => $req->termin_id,
					// 	'crt' => $now,
					// 	'crt_by' => $req->auth->uid,
					// 	'updt' => $now,
					// 	'updt_by' => $req->auth->uid,
					// ];
					// $a_item_pph_id = OrdersAItems::add($insPph);
					// // $sell_price = $sell_price + $insPph['amt_bill_total_flat']; // +
				} else {
					// $a_item_pph_id = $a_item_pph[0]->id;
					// $updtPph = [
					// 	'desc' => "PPH ($req->pph_percent%)",
					// 	'unit_id' => 0,
					// 	'unit_type' => UnitTypes::UNIT_TYPE_PCS,
					// 	'amt_bill_base_flat' => $req->pph_flat,
					// 	'unit_qty' => 1,
					// 	'amt_bill_result_flat' => $req->pph_flat,
					// 	'amt_bill_total_flat' => $req->pph_flat,
					// 	'is_tax_type' => $req->tax_type_kind,
					// 	'updt' => $now,
					// 	'updt_by' => $req->auth->uid,
					// ];
					// OrdersAItems::updt($a_item_pph[0]->id, $updtPph);
					// // if ($updtPph['amt_bill_total_flat'] != $a_item_pph[0]->amt_bill_total_flat) {
					// // 	$sell_price = $sell_price - $a_item_pph[0]->amt_bill_total_flat + $updtPph['amt_bill_total_flat']; // - +
					// // }
					// if ($updtPph['amt_bill_total_flat'] != $a_item_pph[0]->amt_bill_total_flat) {
					// 	// $sell_price = $sell_price - $a_item_pph[0]->amt_bill_total_flat + $updtPph['amt_bill_total_flat']; // - +
					// }
				}
			}

			if ($a_item_disc === false || count($a_item_disc) < 1) {
				if ($req->disc_type == OrdersAItems::AMT_TYPE_PERCENT) {
					$desc = "Discount ($req->disc_percent%)";
				} else {
					$desc = "Discount";
				}
				$insDisc = [
					'ord_id' => $order[0]->ord_id,
					'ord_code' => $order[0]->ord_code,
					'c_termin_id' => $req->termin_id,
					'flow_type' => OrdersInvoices::FLOW_TYPE_BILLING,
					'cash_type' => OrdersInvoices::TYPE_CASH_IN,
					'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
					'desc' => $desc,
					'unit_id' => 0,
					'unit_type' => UnitTypes::UNIT_TYPE_PCS,
					'amt_bill_base_flat' => -$req->disc_flat,
					'unit_qty' => 1,
					'amt_bill_result_flat' => -$req->disc_flat,
					'amt_bill_total_flat' => -$req->disc_flat,
					'ddln_pay_at' => 0,
					'ddln_pay_type' => OrdersAItems::DDLN_PAY_TYPE_TIME,
					'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_YES,
					'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_NO,
					'is_adm_price' => OrdersAItems::IS_ADM_PRICE_NO,
					'only_client' => OrdersAItems::ONLY_CLIENT_YES,
					'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
					'is_disc' => OrdersAItems::IS_DISC_YES,
					'ref_ord_id' => $order[0]->ord_id,
					'ref_ord_code' => $order[0]->ord_code,
					'ref_c_termin_id' => $req->termin_id,
					'crt' => $now,
					'crt_by' => $req->auth->uid,
					'updt' => $now,
					'updt_by' => $req->auth->uid,
				];
				$a_item_disc_id = OrdersAItems::add($insDisc);
				$sell_price = $sell_price + $insDisc['amt_bill_total_flat'];
			} else {
				$a_item_disc_id = $a_item_disc[0]->id;
				if ($req->disc_type == OrdersAItems::AMT_TYPE_PERCENT) {
					$desc = "Discount ($req->disc_percent%)";
				} else {
					$desc = "Discount";
				}
				$updtDisc = [
					'desc' => $desc,
					'unit_id' => 0,
					'unit_type' => UnitTypes::UNIT_TYPE_PCS,
					'amt_bill_base_flat' => -$req->disc_flat,
					'unit_qty' => 1,
					'amt_bill_result_flat' => -$req->disc_flat,
					'amt_bill_total_flat' => -$req->disc_flat,
					'updt' => $now,
					'updt_by' => $req->auth->uid,
				];
				OrdersAItems::updt($a_item_disc[0]->id, $updtDisc);
				if ($updtDisc['amt_bill_total_flat'] != $a_item_disc[0]->amt_bill_total_flat) {
					// $sell_price = $sell_price + $a_item_disc[0]->amt_bill_total_flat; // ngebug
					$sell_price = $sell_price - $a_item_disc[0]->amt_bill_total_flat + $updtDisc['amt_bill_total_flat'];
					// $sell_price = $sell_price + $updtDisc['amt_bill_total_flat'];
				}
			}

			if ($req->tax_type_kind == OrdersAItems::AMT_TAX_TYPE_EXCLUDE) {
				if ($a_item_ppn === false || count($a_item_ppn) < 1) {
					$insPpn = [
						'ord_id' => $order[0]->ord_id,
						'ord_code' => $order[0]->ord_code,
						'c_termin_id' => $req->termin_id,
						'flow_type' => OrdersInvoices::FLOW_TYPE_BILLING,
						'cash_type' => OrdersInvoices::TYPE_CASH_IN,
						'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
						'desc' => "PPN ($req->ppn_percent%)",
						'unit_id' => 0,
						'unit_type' => UnitTypes::UNIT_TYPE_PCS,
						'amt_bill_base_flat' => $req->ppn_flat,
						'unit_qty' => 1,
						'amt_bill_tax_type' => $req->tax_type_kind,
						'amt_bill_result_flat' => $req->ppn_flat,
						'amt_bill_total_flat' => $req->ppn_flat,
						'ddln_pay_at' => 0,
						'ddln_pay_type' => OrdersAItems::DDLN_PAY_TYPE_TIME,
						'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_YES,
						'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_NO,
						'is_adm_price' => OrdersAItems::IS_ADM_PRICE_NO,
						'only_client' => OrdersAItems::ONLY_CLIENT_YES,
						'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
						'is_tax' => OrdersAItems::IS_TAX_YES,
						'is_tax_type' => $req->tax_type_kind,
						'is_ppn' => OrdersAItems::IS_TAX_YES,
						'ref_ord_id' => $order[0]->ord_id,
						'ref_ord_code' => $order[0]->ord_code,
						'ref_c_termin_id' => $req->termin_id,
						'crt' => $now,
						'crt_by' => $req->auth->uid,
						'updt' => $now,
						'updt_by' => $req->auth->uid,
					];
					$a_item_ppn_id = OrdersAItems::add($insPpn);
					$sell_price = $sell_price + $insPpn['amt_bill_total_flat']; // +
				} else {
					$a_item_ppn_id = $a_item_ppn[0]->id;
					$updtPpn = [
						'desc' => "PPN ($req->ppn_percent%)",
						'unit_id' => 0,
						'unit_type' => UnitTypes::UNIT_TYPE_PCS,
						'amt_bill_base_flat' => $req->ppn_flat,
						'unit_qty' => 1,
						'amt_bill_result_flat' => $req->ppn_flat,
						'amt_bill_total_flat' => $req->ppn_flat,
						'is_tax_type' => $req->tax_type_kind,
						'updt' => $now,
						'updt_by' => $req->auth->uid,
					];
					OrdersAItems::updt($a_item_ppn[0]->id, $updtPpn);
					// if ($updtPpn['amt_bill_total_flat'] != $a_item_ppn[0]->amt_bill_total_flat) {
					// 	$sell_price = $sell_price - $a_item_ppn[0]->amt_bill_total_flat + $updtPpn['amt_bill_total_flat']; // - +
					// }
					if ($updtPpn['amt_bill_total_flat'] != $a_item_ppn[0]->amt_bill_total_flat) {
						$sell_price = $sell_price - $a_item_ppn[0]->amt_bill_total_flat + $updtPpn['amt_bill_total_flat']; // - +
					}
				}

				if ($a_item_pph === false || count($a_item_pph) < 1) {
					// $insPph = [
					// 	'ord_id' => $order[0]->ord_id,
					// 	'ord_code' => $order[0]->ord_code,
					// 	'c_termin_id' => $req->termin_id,
					// 	'flow_type' => OrdersInvoices::FLOW_TYPE_BILLING,
					// 	'cash_type' => OrdersInvoices::TYPE_CASH_IN,
					// 	'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
					// 	'desc' => "PPH ($req->pph_percent%)",
					// 	'unit_id' => 0,
					// 	'unit_type' => UnitTypes::UNIT_TYPE_PCS,
					// 	'amt_bill_base_flat' => $req->pph_flat,
					// 	'unit_qty' => 1,
					// 	'amt_bill_tax_type' => $req->tax_type_kind,
					// 	'amt_bill_result_flat' => $req->pph_flat,
					// 	'amt_bill_total_flat' => $req->pph_flat,
					// 	'ddln_pay_at' => 0,
					// 	'ddln_pay_type' => OrdersAItems::DDLN_PAY_TYPE_TIME,
					// 	'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_YES,
					// 	'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_NO,
					// 	'is_adm_price' => OrdersAItems::IS_ADM_PRICE_NO,
					// 	'only_client' => OrdersAItems::ONLY_CLIENT_YES,
					// 	'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
					// 	'is_tax' => OrdersAItems::IS_TAX_YES,
					// 	'is_tax_type' => $req->tax_type_kind,
					// 	'is_pph' => OrdersAItems::IS_TAX_YES,
					// 	'ref_ord_id' => $order[0]->ord_id,
					// 	'ref_ord_code' => $order[0]->ord_code,
					// 	'ref_c_termin_id' => $req->termin_id,
					// 	'crt' => $now,
					// 	'crt_by' => $req->auth->uid,
					// 	'updt' => $now,
					// 	'updt_by' => $req->auth->uid,
					// ];
					// $a_item_pph_id = OrdersAItems::add($insPph);
					// $sell_price = $sell_price + $insPph['amt_bill_total_flat']; // +
				} else {
					// $a_item_pph_id = $a_item_pph[0]->id;
					// $updtPph = [
					// 	'desc' => "PPH ($req->pph_percent%)",
					// 	'unit_id' => 0,
					// 	'unit_type' => UnitTypes::UNIT_TYPE_PCS,
					// 	'amt_bill_base_flat' => $req->pph_flat,
					// 	'unit_qty' => 1,
					// 	'amt_bill_result_flat' => $req->pph_flat,
					// 	'amt_bill_total_flat' => $req->pph_flat,
					// 	'is_tax_type' => $req->tax_type_kind,
					// 	'updt' => $now,
					// 	'updt_by' => $req->auth->uid,
					// ];
					// OrdersAItems::updt($a_item_pph[0]->id, $updtPph);
					// // if ($updtPph['amt_bill_total_flat'] != $a_item_pph[0]->amt_bill_total_flat) {
					// // 	$sell_price = $sell_price - $a_item_pph[0]->amt_bill_total_flat + $updtPph['amt_bill_total_flat']; // - +
					// // }
					// if ($updtPph['amt_bill_total_flat'] != $a_item_pph[0]->amt_bill_total_flat) {
					// 	$sell_price = $sell_price - $a_item_pph[0]->amt_bill_total_flat + $updtPph['amt_bill_total_flat']; // - +
					// }
				}
			}

			Orders::updateOrder($order[0]->ord_id, [
				'price' => $sell_price,
				// 'price' => round($req->total),
			]);

			if ($is_updt) {
				// $sell_price = $sell_price - $ord_invc[0]->amt_disc_flat - $ord_invc[0]->tax_flat;
				OrdersInvoices::updt($ord_invc[0]->id, [
					'code' => $code,
					'ord_a_item_ids' => $req->items,
					'amt_base_flat' => $req->subtotal,
					'amt_disc_type' => $req->disc_type,
					'amt_disc_percent' => $req->disc_percent,
					'amt_disc_flat' => $req->disc_flat,
					'amt_tax_type' => $req->tax_type,
					'amt_tax_type_kind' => $req->tax_type_kind,
					'amt_tax_ppn_percent' => $req->ppn_percent,
					'amt_tax_ppn_flat' => $req->ppn_flat,
					'amt_tax_pph_percent' => $req->pph_percent,
					'amt_tax_pph_flat' => $req->pph_flat,
					'amt_tax_flat' => $req->tax_flat,
					'amt_total_flat' => round($req->total),
					// 'bank_id' => Banks::DFT_BANK_ID,
					// 'bank_code' => Banks::DFT_BANK_CODE,
					// 'bank_short_name' => Banks::DFT_BANK_NAME,
					// 'bank_name' => Banks::DFT_BANK_SHORT_NAME,
					// 'bank_acc_name' => Banks::DFT_BANK_ACC_NAME,
					// 'bank_acc_number' => Banks::DFT_BANK_ACC_NUMBER,
					'invc_at' => $now,
					// 'invc_for_uid' => $order[0]->c_id,
					// 'invc_for_ptid' => $order[0]->c_pt_id,
					// 'invc_for_type' => OrdersInvoices::INVC_FOR_CLIENT,
					// 'pay_due_type' => OrdersInvoices::PAY_DUE_TYPE_14_WORK_DAY,
					'a_item_ppn_id' => $a_item_ppn_id,
					'a_item_pph_id' => $a_item_pph_id,
					'a_item_disc_id' => $a_item_disc_id,
					'is_gnrt_invc' => $req->is_gnrt_invc ?? 0,
					'updt' => $now,
					'updt_by' => $req->auth->uid,
				]);
			} else {
				$invc_id = OrdersInvoices::add([
					'code' => $code,
					'ord_id' => $order[0]->ord_id,
					'ord_code' => $order[0]->ord_code,
					'flow_type' => OrdersInvoices::FLOW_TYPE_BILLING,
					'cash_type' => OrdersInvoices::TYPE_CASH_IN,
					'c_termin_id' => $req->termin_id,
					'ord_a_item_ids' => $req->items,
					'amt_base_flat' => $req->subtotal,
					'amt_disc_type' => $req->disc_type,
					'amt_disc_percent' => $req->disc_percent,
					'amt_disc_flat' => $req->disc_flat,
					'amt_tax_type' => $req->tax_type,
					'amt_tax_type_kind' => $req->tax_type_kind,
					'amt_tax_ppn_percent' => $req->ppn_percent,
					'amt_tax_ppn_flat' => $req->ppn_flat,
					'amt_tax_pph_percent' => $req->pph_percent,
					'amt_tax_pph_flat' => $req->pph_flat,
					'amt_tax_flat' => $req->tax_flat,
					'amt_total_flat' => $req->total,
					'bank_id' => Banks::DFT_BANK_ID,
					'bank_code' => Banks::DFT_BANK_CODE,
					'bank_short_name' => Banks::DFT_BANK_NAME,
					'bank_name' => Banks::DFT_BANK_SHORT_NAME,
					'bank_acc_name' => Banks::DFT_BANK_ACC_NAME,
					'bank_acc_number' => Banks::DFT_BANK_ACC_NUMBER,
					'invc_at' => $now,
					'invc_for_uid' => $order[0]->c_id,
					'invc_for_ptid' => $order[0]->c_pt_id,
					'invc_for_type' => OrdersInvoices::INVC_FOR_CLIENT,
					'pay_due_type' => OrdersInvoices::PAY_DUE_TYPE_14_WORK_DAY,
					'a_item_ppn_id' => $a_item_ppn_id,
					'a_item_pph_id' => $a_item_pph_id,
					'a_item_disc_id' => $a_item_disc_id,
					'is_gnrt_invc' => $req->is_gnrt_invc ?? 0,
					'crt' => $now,
					'crt_by' => $req->auth->uid,
					'crt_type' => OrdersInvoices::CRT_TYPE_FINANCE,
					'updt' => $now,
					'updt_by' => $req->auth->uid,
				]);
			}

			$apiResp = Responses::success('success create / update invoice');
			$apiResp['id'] = $invc_id;
			$apiResp['code'] = $code;

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			if (count($url_up_paid_proof_base64) > 0) {
				foreach ($url_up_paid_proof_base64 as $path) {
					Storage::disk('public')->delete($path);
				}
			}
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_crt_updt_tax(Request $req)
	{
		try {
			$now = time();

			$input = [
				'termin_id' => $req->termin_id,
				'ord_id' => $req->ord_id,
				'ord_code' => $req->ord_code,
				'invc_tax_type' => $req->invc_tax_type,
				'invc_tax_ppn_percent' => $req->invc_tax_ppn_percent,
				'invc_tax_pph_percent' => $req->invc_tax_pph_percent,
			];
			$rulesInput = [
				'ord_id' => 'required|integer|not_in:0',
				'ord_code' => 'required|integer|not_in:0',
				'termin_id' => 'required|integer|not_in:0',
				'invc_tax_type' => 'required|numeric',
				'invc_tax_ppn_percent' => 'required|numeric',
				'invc_tax_pph_percent' => 'required|numeric',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$order = Orders::showOrder([
				'id' => $req->ord_id,
				'get_client_pt' => 1,
			]);
			if (count($order) < 1 || $order === false) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			$a_item_ppn = OrdersAItems::listAItems([
				'c_termin_id' => $req->termin_id,
				'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
				'is_tax' => OrdersAItems::IS_TAX_YES,
				'is_ppn' => OrdersAItems::IS_TAX_YES,
			]);

			$a_item_pph = OrdersAItems::listAItems([
				'c_termin_id' => $req->termin_id,
				'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
				'is_tax' => OrdersAItems::IS_TAX_YES,
				'is_pph' => OrdersAItems::IS_TAX_YES,
			]);

			DB::beginTransaction();

			$sell_price = $order[0]->price;

			$ord_invc = OrdersInvoices::getByTerminId($req->termin_id);
			if (count($ord_invc) < 1 || $ord_invc === false) {}
			else {
				OrdersInvoices::updt($ord_invc[0]->id, [
					'is_gnrt_invc' => OrdersInvoices::IS_GNRT_INVC_NO,
				]);
			}

			OrdersTermins::updt($req->termin_id, [
				'termin_tax_type' => $req->invc_tax_type,
				'termin_tax_ppn_percent' => $req->invc_tax_ppn_percent,
				'termin_tax_pph_percent' => $req->invc_tax_pph_percent,
			]);

			if ($a_item_ppn === false || count($a_item_ppn) < 1) {}
			else {
				if ($a_item_ppn[0]->amt_bill_tax_type === OrdersAItems::AMT_TAX_TYPE_INCLUDE) {
					$sell_price = $sell_price - $a_item_ppn[0]->amt_bill_total_flat;
				} else if ($a_item_ppn[0]->amt_bill_tax_type === OrdersAItems::AMT_TAX_TYPE_EXCLUDE) {
					$sell_price = $sell_price - $a_item_ppn[0]->amt_bill_total_flat;
				}
				OrdersAItems::dlt($a_item_ppn[0]->id);
			}

			if ($a_item_pph === false || count($a_item_pph) < 1) {}
			else {
				if ($a_item_pph[0]->amt_bill_tax_type === OrdersAItems::AMT_TAX_TYPE_INCLUDE) {
					$sell_price = $sell_price - $a_item_pph[0]->amt_bill_total_flat;
				} else if ($a_item_pph[0]->amt_bill_tax_type === OrdersAItems::AMT_TAX_TYPE_EXCLUDE) {
					$sell_price = $sell_price - $a_item_pph[0]->amt_bill_total_flat;
				}
				OrdersAItems::dlt($a_item_pph[0]->id);
			}

			Orders::updateOrder($order[0]->ord_id, [
				'price' => $sell_price,
				// 'price' => round($req->total),
			]);

			$apiResp = Responses::success('success save tax');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_confirm_invc(Request $req)
	{
		$url_up_paid_proof_base64 = [];
		try {
			$now = time();

			$input = [
				'invc_id' => $req->invc_id,
				'invc_code' => $req->invc_code,
				'amt_invoicing' => $req->amt_invoicing,
				'amt_bill_confirm' => $req->amt_bill_confirm,
				'amt_bill_confirm_note' => $req->amt_bill_confirm_note,
			];
			$rulesInput = [
				'invc_id' => 'required|integer|not_in:0',
				'invc_code' => 'nullable|numeric',
				'amt_invoicing' => 'required|numeric',
				'amt_bill_confirm' => 'required|numeric',
				'amt_bill_confirm_note' => 'nullable|string',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			// if (!$req->up_paid_proof_base64 || count($req->up_paid_proof_base64) < 1) {
			// 	$apiResp = Responses::bad_input('bukti pembayaran wajib diisi');
			// 	return new Response($apiResp, $apiResp['meta']['code']);
			// }

			$ord_invc = OrdersInvoices::getById($req->invc_id);
			if (count($ord_invc) < 1 || $ord_invc === false) {
				$apiResp = Responses::not_found('invoice not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$item_ids = explode(',', $ord_invc[0]->ord_a_item_ids);
			$order = Orders::showOrder(['id' => $ord_invc[0]->ord_id]);

			// $a_item_ppn = OrdersAItems::listAItems([
			// 	'c_termin_id' => $req->termin_id,
			// 	'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
			// 	'is_tax' => OrdersAItems::IS_TAX_YES,
			// ]);

			// $a_item_disc = OrdersAItems::listAItems([
			// 	'c_termin_id' => $req->termin_id,
			// 	'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
			// 	'is_disc' => OrdersAItems::IS_DISC_YES,
			// ]);

			DB::beginTransaction();

			$updtOrdersInvoices = [
				'updt' => $now,
				'updt_by' => $req->auth->uid,
				'is_paid' => OrdersInvoices::IS_PAID_YES,
				'paid_at' => $now,
				'paid_by' => $req->auth->uid,
			];

			if ($ord_invc[0]->c_termin_id !== 0) {
				$termin = OrdersTermins::getById($ord_invc[0]->c_termin_id);
				if ($termin[0]->termin_is_paid !== OrdersTermins::IS_PAID_YES) {
					OrdersTermins::updt($ord_invc[0]->c_termin_id, [
						'termin_is_paid' => OrdersTermins::IS_PAID_YES,
						'termin_paid_at' => $now,
						'termin_paid_by' => $req->auth->uid,
						'amt_bill_confirm' => $req->amt_bill_confirm,
						'amt_bill_confirm_note' => $req->amt_bill_confirm_note,
						'updt' => $now,
						'updt_by' => $req->auth->uid,
					]);
				}
			}

			$qty = 1;
			$selisih = $req->amt_bill_confirm - $req->amt_invoicing;
			OrdersAItems::add([
				'ord_id' => $ord_invc[0]->ord_id,
				'ord_code' => $ord_invc[0]->ord_code,
				'flow_type' => OrdersAItems::FLOW_TYPE_BILLING,
				'cash_type' => OrdersAItems::TYPE_CASH_IN,
				'c_termin_id' => $ord_invc[0]->c_termin_id,
				'a_item_type' => OrdersAItems::A_TYPE_SECONDARY,
				// 'desc' => $main_item_dec . "<br>Pembayaran termin 1",
				'desc' => 'Selisih dari nilai yang ditagihkan dan diterima pada trx_code:' . $ord_invc[0]->ord_code,
				'unit_id' => 0,
				'unit_type' => UnitTypes::UNIT_TYPE_PCS,
				'unit_qty' => $qty,
				'amt_bill_base_flat' => $selisih,
				'amt_bill_result_flat' => $selisih,
				'amt_bill_total_flat' => $selisih * $qty,
				'ddln_pay_at' => 0,
				'ddln_pay_type' => OrdersAItems::DDLN_PAY_TYPE_TIME,
				'img_proof_submission' => null,
				'img_proof_payment' => null,
				'bank_id' => Banks::DFT_BANK_ID,
				'bank_code' => Banks::DFT_BANK_CODE,
				'bank_name' => Banks::DFT_BANK_NAME,
				'bank_short_name' => Banks::DFT_BANK_SHORT_NAME,
				'bank_acc_number' => Banks::DFT_BANK_ACC_NUMBER,
				'bank_acc_name' => Banks::DFT_BANK_ACC_NAME,
				// 'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_YES, // seharusnya yang ini kalau diaktifin (mau dihitung di summary / ledger balance)
				'invc_to_client' => OrdersAItems::INVC_TO_CLIENT_NO,
				'calc_to_vdr' => OrdersAItems::CALC_TO_VDR_NO,
				'is_adm_price' => OrdersAItems::IS_ADM_PRICE_NO,
				// 'only_client' => OrdersAItems::ONLY_CLIENT_YES, // seharusnya yang ini kalau diaktifin (mau dihitung di summary / ledger balance)
				'only_client' => OrdersAItems::ONLY_CLIENT_NO,
				'is_hidden' => OrdersAItems::IS_HIDDEN_YES,
				'is_substract' => OrdersAItems::IS_SUBTRACT_YES,
				'ref_ord_id' => $ord_invc[0]->ord_id,
				'ref_ord_code' => $ord_invc[0]->ord_code,
				'ref_c_termin_id' => $ord_invc[0]->c_termin_id,
				'is_bill_paid' => OrdersAItems::IS_PAID_YES,
				'paid_bill_at' => $now,
				'paid_bill_by' => $req->auth->uid,
				'crt' => $now,
				'crt_by' => $req->auth->uid,
				'updt' => $now,
				'updt_by' => $req->auth->uid,
			]);

			foreach ($item_ids as $id) {
				OrdersAItems::updt($id, [
					'updt' => $now,
					'updt_by' => $req->auth->uid,
					'is_bill_paid' => OrdersAItems::IS_PAID_YES,
					'paid_bill_at' => $now,
					'paid_bill_by' => $req->auth->uid,
				]);
			}

			if ($ord_invc[0]->a_item_ppn_id != 0) {
				OrdersAItems::updt($ord_invc[0]->a_item_ppn_id, [
					'updt' => $now,
					'updt_by' => $req->auth->uid,
					'is_bill_paid' => OrdersAItems::IS_PAID_YES,
					'paid_bill_at' => $now,
					'paid_bill_by' => $req->auth->uid,
				]);
			}
			if ($ord_invc[0]->a_item_pph_id != 0) {
				OrdersAItems::updt($ord_invc[0]->a_item_pph_id, [
					'updt' => $now,
					'updt_by' => $req->auth->uid,
					'is_bill_paid' => OrdersAItems::IS_PAID_YES,
					'paid_bill_at' => $now,
					'paid_bill_by' => $req->auth->uid,
				]);
			}
			if ($ord_invc[0]->a_item_disc_id != 0) {
				OrdersAItems::updt($ord_invc[0]->a_item_disc_id, [
					'updt' => $now,
					'updt_by' => $req->auth->uid,
					'is_bill_paid' => OrdersAItems::IS_PAID_YES,
					'paid_bill_at' => $now,
					'paid_bill_by' => $req->auth->uid,
				]);
			}

			OrdersInvoices::updt($ord_invc[0]->id, $updtOrdersInvoices);

			$updtOrd = [];

			$checkPaidOff = Finance::checkJustPaidOff($ord_invc[0]->ord_id);
			if ($checkPaidOff['invc_paid'] === 1) {
				$updtOrd['is_invc_paid'] = Orders::IS_PAID_YES;
				$updtOrd['invc_paid_at'] = $now;
			}
			if ($checkPaidOff['vdr_paid'] === 1) {
				$updtOrd['is_vdr_paid'] = Orders::IS_PAID_YES;
				$updtOrd['vdr_paid_at'] = $now;
				// kalau vhc & driver bisa order lagi setelah pembayaran lunas
				// Vehicles::updateVehicle($order[0]->vhc_id, [
				// 	'is_in_ord' => Vehicles::IN_ORD_NO,
				// 	'ord_id' => 0,
				// 	'ord_code' => 0,
				// ]);
				// Drivers::updateDriver($order[0]->drv_id, [
				// 	'is_in_ord' => Drivers::IN_ORD_NO,
				// 	'ord_id' => 0,
				// 	'ord_code' => 0,
				// ]);
			}
			if ($checkPaidOff['invc_vdr_paid'] === 1 || $checkPaidOff['invc_vdr_paid'] === 2) {
				if ($order[0]->status === Orders::STTS_DROP || $order[0]->status === Orders::STTS_CLIENT_PAY || $order[0]->status === Orders::STTS_VENDOR_PAYED) {
					$updtOrd['status'] = Orders::STTS_CLOSE;
				}
			}

			if (count($updtOrd) > 0) {
				Orders::updateOrder($ord_invc[0]->ord_id, $updtOrd);
			}

			// $currentBill = Finance::listBillings(['ord_id' => $ord_invc[0]->ord_id]);
			// $currentPay = Finance::listPayments(['ord_id' => $ord_invc[0]->ord_id]);
			// if ($currentBill[0]->total_billing === $currentBill[0]->total_payed || $currentPay[0]->total_payment === $currentPay[0]->total_payed) {
			// 	$updtOrd = [];
			// 	if ($currentBill[0]->total_billing === $currentBill[0]->total_payed) {
			// 		if ($order[0]->is_invc_paid !== Orders::IS_PAID_YES) {
			// 			$updtOrd['is_invc_paid'] = Orders::IS_PAID_YES;
			// 			$updtOrd['invc_paid_at'] = $now;
			// 		}
			// 	}
			// 	if ($currentPay[0]->total_payment === $currentPay[0]->total_payed) {
			// 		if ($order[0]->is_vdr_paid !== Orders::IS_PAID_YES) {
			// 			$updtOrd['is_vdr_paid'] = Orders::IS_PAID_YES;
			// 			$updtOrd['vdr_paid_at'] = $now;
			// 			Vehicles::updateVehicle($order[0]->vhc_id, [
			// 				'is_in_ord' => Vehicles::IN_ORD_NO,
			// 				'ord_id' => 0,
			// 				'ord_code' => 0,
			// 			]);
			// 			Drivers::updateDriver($order[0]->drv_id, [
			// 				'is_in_ord' => Drivers::IN_ORD_NO,
			// 				'ord_id' => 0,
			// 				'ord_code' => 0,
			// 			]);
			// 		}
			// 	}
			// 	if ($currentBill[0]->total_billing === $currentBill[0]->total_payed && $currentPay[0]->total_payment === $currentPay[0]->total_payed) {
			// 		$updtOrd['status'] = Orders::STTS_CLOSE;
			// 	}
			// 	if (count($updtOrd) > 0) {
			// 		Orders::updateOrder($ord_invc[0]->ord_id, $updtOrd);
			// 	}
			// }

			$apiResp = Responses::success('success paid invoice');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			if (count($url_up_paid_proof_base64) > 0) {
				foreach ($url_up_paid_proof_base64 as $path) {
					Storage::disk('public')->delete($path);
				}
			}
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_finance_save_note(Request $req, $ord_id)
	{
		$url_up_paid_proof_base64 = [];
		try {
			$now = time();

			$input = [
				'ord_id' => $ord_id,
				'fnnc_note' => $req->fnnc_note,
			];
			$rulesInput = [
				'ord_id' => 'required|integer|not_in:0',
				'fnnc_note' => 'required|string|min:2',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$order = Orders::showOrder(['id' => $ord_id]);
			if (count($order) < 1 || $order === false) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			DB::beginTransaction();

			$updtOrd = [
				'fnnc_note' => $req->fnnc_note,
			];
			Orders::updateOrder($order[0]->ord_id, $updtOrd);

			$apiResp = Responses::success('success save note');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			if (count($url_up_paid_proof_base64) > 0) {
				foreach ($url_up_paid_proof_base64 as $path) {
					Storage::disk('public')->delete($path);
				}
			}
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}


	// DANA || CHECKPOINTS
	public function api_list_pocket_tf_history(Request $req)
	{
		try {
			$now = time();
			$input = [];
			$rulesInput = [];

			// validasi input
			// $isValidInput = Validator::make($input, $rulesInput);
			// if (!$isValidInput->passes()) {
			// 	$apiResp = Responses::bad_input($isValidInput->messages()->first());
			// 	return new Response($apiResp, $apiResp['meta']['code']);
			// }

			$filter = [
				'tf_method' => OrdersCheckpoints::TF_METHOD_DANA,
				'where_not_tf_at' => '0',
				'order_by' => 'point.tf_at DESC',
			];
			// $historys = OrdersLogsTf::listLogsTf($filter);
			$historys = OrdersCheckpoints::listCheckpoints($filter);

			$i = 0;
			foreach ($historys as $key => $row) {
				$historys[$key]->DT_RowIndex = ++$i;
				$historys[$key]->action = '-';
			}
			$apiResp = Responses::success('success');
			$apiResp['data'] = $historys;
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	public function api_resend_pocket(Request $req)
	{
		try {
			$now = time();
			$input = [];
			$rulesInput = [];

			$input = [
				'ord_checkpoint_id' => $req->ord_checkpoint_id,
			];
			$rulesInput = [
				'ord_checkpoint_id' => 'required|integer|not_in:0',
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$filter = [
				'id' => $req->ord_checkpoint_id,
				'limit' => '1',
			];
			$historys = OrdersCheckpoints::listCheckpoints($filter);
			if (count($historys) < 1) {
				$apiResp = Responses::bad_request('Riwayat transfer tidak ditemukan');
				return new Response($apiResp, $apiResp['meta']['code']);
			}

			$order = Orders::showOrder([
				'id' => $historys[0]->ord_id,
				'get_drv_bank' => 1,
				'ord_pck_drop_id' => $req->ord_pck_drop_id,
				'couple_pck_drop' => 1,
			]);
			if (count($order) < 1) {
				$apiResp = Responses::not_found('order not found');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			$drvPhone = DrvPhoneDevices::get(['drv_id' => $order[0]->drv_id]);
			if (count($drvPhone) < 1) {
				$apiResp = Responses::bad_request('Driver belum pernah melakukan login');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}

			$admins = Users::getUsersActiveByRole(Users::ROLE_FINANCE);
			$admins_data = [];
			foreach ($admins as $k => $v) {
				array_push($admins_data, [
					"admin_id" => $v->id,
					"admin_name" => $v->first_name,
					"admin_phone" => $v->phone_code . " " . implode(" ", str_split($v->phone, 4)),
					"admin_mail" => $v->email,
					"admin_addr" => ""
				]);
			}

			$dana = Dana::getDanaById(Dana::PK_ID);
			if (count($dana) < 1) {
				$apiResp = Responses::bad_request('dana error');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$dana = $dana[0];

			DB::beginTransaction();

			$url = env('API_DANA_BINGCORP') . '/order/create';
			$guzReq = new GuzzleClient();
			$json = [
				'ord_id' => $order[0]->ord_id,
				'ord_code' => $order[0]->ord_code,
				'checkpoint_id' => $historys[0]->ord_checkpoint_id,
				'bank_code' => $order[0]->drv_bank_code,
				'bank_name' => $order[0]->drv_bank_name,
				'bank_branch' => $order[0]->drv_bank_branch_name ?? null,
				'amt' => $historys[0]->pocket_total,
				'acc_name' => $order[0]->drv_bank_acc_name,
				'acc_number' => $order[0]->drv_bank_acc_number,
				'device_id' => $drvPhone[0]->device_id,
			];
			if ($dana->amt > $historys[0]->pocket_total && $dana->amt > Dana::MINIMUM_AMT) {
				try {
					$respDana = $guzReq->request('POST', $url, [
						'headers' => [
							// 'Host' => $_SERVER['SERVER_ADDR'] ?? '127.0.0.1',
							'User-Agent' => 'curl/7.65.3',
							'Accept' => '*/*',
							'Accept-Encoding' => 'gzip, deflate, br',
							// 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
							'Content-Type' => 'application/json',
							// 'Connection' => 'keep-alive',
						],
						'json' => $json,
					]);
					$isValidDana = 1;
					$bodyDana = json_decode($respDana->getBody()->getContents());
					if ($respDana->getStatusCode() != 200 || $bodyDana->meta->code != 200) {
						$isValidDana = 0;
						// DB::rollBack();
						OrdersLogsTf::addLogsTf([
							'ord_id' => $order[0]->ord_id,
							'ord_code' => $order[0]->ord_code,
							'type' => OrdersLogsTf::TYPE_TF_CHECKPOINT,
							'checkpoint_id' => $historys[0]->ord_checkpoint_id,
							'amount' => $historys[0]->pocket_total,
							'stts' => OrdersLogsTf::STTS_FAIL,
							'fail_at' => time(),
							'note' => $bodyDana->data->note,
							'bank_id' => $order[0]->drv_bank_id,
							'bank_name' => $order[0]->drv_bank_name,
							'bank_code' => $order[0]->drv_bank_code,
							'bank_short_name' => $order[0]->drv_bank_short_name,
							'bank_branch_name' => $order[0]->drv_bank_branch_name ?? null,
							'bank_acc_name' => $order[0]->drv_bank_acc_name,
							'bank_acc_number' => $order[0]->drv_bank_acc_number,
							'method' => OrdersLogsTf::METHOD_DANA,
							'url' => $url,
							'ref_code' => $bodyDana->data->dana_reference_no,
							'req_data' => json_encode($json),
							'resp_data' => json_encode($bodyDana),
							'crt' => time(),
							'updt' => time(),
						]);
						OrdersCheckpoints::updateCheckpoint($historys[0]->ord_checkpoint_id, [
							'pocket_is_paid' => OrdersCheckpoints::IS_TF_FAIL,
							'pocket_paid_note' => $bodyDana->data->note,
							'bank_id' => $order[0]->drv_bank_id,
							'bank_name' => $order[0]->drv_bank_name,
							'bank_code' => $order[0]->drv_bank_code,
							'bank_short_name' => $order[0]->drv_bank_short_name,
							'bank_branch_name' => $order[0]->drv_bank_branch_name ?? null,
							'bank_acc_name' => $order[0]->drv_bank_acc_name,
							'bank_acc_number' => $order[0]->drv_bank_acc_number,
							'tf_method' => OrdersCheckpoints::TF_METHOD_DANA,
							'tf_at' => $now,
							'tf_url' => $url,
							'tf_ref_code' => $bodyDana->data->dana_reference_no,
							'tf_note' => $bodyDana->data->note,
							'tf_req_data' => json_encode($json),
							'tf_resp_data' => json_encode($bodyDana),
						]);
						$apiResp = Responses::bad_request('Gagal transfer ke rekening driver');
						return (new Response($apiResp, $apiResp['meta']['code']));
					}
		
					if ($isValidDana === 1) {
						OrdersLogsTf::addLogsTf([
							'ord_id' => $order[0]->ord_id,
							'ord_code' => $order[0]->ord_code,
							'type' => OrdersLogsTf::TYPE_TF_CHECKPOINT,
							'checkpoint_id' => $historys[0]->ord_checkpoint_id,
							'amount' => $historys[0]->pocket_total,
							'stts' => OrdersLogsTf::STTS_PAID,
							'paid_at' => time(),
							'note' => $bodyDana->data->note,
							'bank_id' => $order[0]->drv_bank_id,
							'bank_name' => $order[0]->drv_bank_name,
							'bank_code' => $order[0]->drv_bank_code,
							'bank_short_name' => $order[0]->drv_bank_short_name,
							'bank_branch_name' => $order[0]->drv_bank_branch_name ?? null,
							'bank_acc_name' => $order[0]->drv_bank_acc_name,
							'bank_acc_number' => $order[0]->drv_bank_acc_number,
							'method' => OrdersLogsTf::METHOD_DANA,
							'url' => $url,
							'ref_code' => $bodyDana->data->dana_reference_no,
							'req_data' => json_encode($json),
							'resp_data' => json_encode($bodyDana),
							'crt' => time(),
							'updt' => time(),
						]);
						OrdersCheckpoints::updateCheckpoint($historys[0]->ord_checkpoint_id, [
							'pocket_is_paid' => OrdersCheckpoints::IS_PAID,
							'pocket_paid_at' => $now,
							// 'pocket_paid_by' => $req->auth->id,
							'bank_id' => $order[0]->drv_bank_id,
							'bank_name' => $order[0]->drv_bank_name,
							'bank_code' => $order[0]->drv_bank_code,
							'bank_short_name' => $order[0]->drv_bank_short_name,
							'bank_branch_name' => $order[0]->drv_bank_branch_name ?? null,
							'bank_acc_name' => $order[0]->drv_bank_acc_name,
							'bank_acc_number' => $order[0]->drv_bank_acc_number,
							'tf_method' => OrdersCheckpoints::TF_METHOD_DANA,
							'tf_at' => $now,
							'tf_url' => $url,
							'tf_ref_code' => $bodyDana->data->dana_reference_no ?? 0,
							'tf_note' => $bodyDana->data->note ?? 0,
							'tf_req_data' => json_encode($json),
							'tf_resp_data' => json_encode($bodyDana),
						]);
						Dana::updateDana($dana->id, ['amt' => DB::raw('amt-'.$historys[0]->pocket_total)]);
					}
				} catch (\GuzzleHttp\Exception\BadResponseException $e) {
					$respDana = $e->getResponse();
					$bodyDana = json_decode($respDana->getBody()->getContents());
					// DB::rollBack();
					OrdersLogsTf::addLogsTf([
						'ord_id' => $order[0]->ord_id,
						'ord_code' => $order[0]->ord_code,
						'type' => OrdersLogsTf::TYPE_TF_CHECKPOINT,
						'checkpoint_id' => $historys[0]->ord_checkpoint_id,
						'amount' => $historys[0]->pocket_total,
						'stts' => OrdersLogsTf::STTS_FAIL,
						'fail_at' => time(),
						'note' => $bodyDana->data->note,
						'bank_id' => $order[0]->drv_bank_id,
						'bank_name' => $order[0]->drv_bank_name,
						'bank_code' => $order[0]->drv_bank_code,
						'bank_short_name' => $order[0]->drv_bank_short_name,
						'bank_branch_name' => $order[0]->drv_bank_branch_name ?? null,
						'bank_acc_name' => $order[0]->drv_bank_acc_name,
						'bank_acc_number' => $order[0]->drv_bank_acc_number,
						'method' => OrdersLogsTf::METHOD_DANA,
						'url' => $url,
						'ref_code' => $bodyDana->data->dana_reference_no,
						'req_data' => json_encode($json),
						'resp_data' => json_encode($bodyDana),
						'crt' => time(),
						'updt' => time(),
					]);
					OrdersCheckpoints::updateCheckpoint($historys[0]->ord_checkpoint_id, [
						'pocket_is_paid' => OrdersCheckpoints::IS_TF_FAIL,
						'pocket_paid_note' => $bodyDana->data->note,
						'bank_id' => $order[0]->drv_bank_id,
						'bank_name' => $order[0]->drv_bank_name,
						'bank_code' => $order[0]->drv_bank_code,
						'bank_short_name' => $order[0]->drv_bank_short_name,
						'bank_branch_name' => $order[0]->drv_bank_branch_name ?? null,
						'bank_acc_name' => $order[0]->drv_bank_acc_name,
						'bank_acc_number' => $order[0]->drv_bank_acc_number,
						'tf_method' => OrdersCheckpoints::TF_METHOD_DANA,
						'tf_at' => $now,
						'tf_url' => $url,
						'tf_ref_code' => $bodyDana->data->dana_reference_no,
						'tf_note' => $bodyDana->data->note,
						'tf_req_data' => json_encode($json),
						'tf_resp_data' => json_encode($bodyDana),
					]);
					$apiResp = Responses::bad_request('Gagal transfer ke rekening driver');
					return (new Response($apiResp, $apiResp['meta']['code']));
				}
			} else {
				$url = env('API_URL_NODE') . '/order/finance_info_dana_amount';
				$guzReq = new GuzzleClient();
				$respNode = $guzReq->request('POST', $url, [
					'headers' => [
						'Host' => $_SERVER['SERVER_ADDR'] ?? '127.0.0.1',
						'User-Agent' => 'curl/7.65.3',
						'Accept' => '*/*',
						'Accept-Encoding' => 'gzip, deflate, br',
						// 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
						// 'Connection' => 'keep-alive',
					],
					'json' => [
						"trx_code" => $order[0]->ord_code,
						"drv_name" => $order[0]->drv_name,
						"pickup_zone_title" => $order[0]->pck_name,
						"pickup_zone_addr" => $order[0]->pck_addr,
						"drop_zone_title" => $order[0]->drop_name,
						"drop_zone_addr" => $order[0]->drop_addr,
						"pocket_total" => 'Rp'.number_format($historys[0]->pocket_total, 0, ',', '.'),
						"bank_name" => $order[0]->drv_bank_name,
						"bank_code" => $order[0]->drv_bank_code,
						"bank_branch_name" => $order[0]->drv_bank_branch_name ?? '',
						"bank_acc_name" => $order[0]->drv_bank_acc_name,
						"bank_acc_no" => $order[0]->drv_bank_acc_number,
						"admins" => $admins_data
					],
				]);
				if ($respNode->getStatusCode() != 200) {
					DB::rollBack();
					$apiResp = Responses::bad_request('gagal mengirim email ke finance');
					return (new Response($apiResp, $apiResp['meta']['code']));
				}
				$body = json_decode($respNode->getBody()->getContents());
			}

			DB::commit();

			$url = env('API_URL_NODE') . '/order/finance_info_tf_pocket';
			$guzReq = new GuzzleClient();
			$respNode = $guzReq->request('POST', $url, [
				'headers' => [
					'Host' => $_SERVER['SERVER_ADDR'] ?? '127.0.0.1',
					'User-Agent' => 'curl/7.65.3',
					'Accept' => '*/*',
					'Accept-Encoding' => 'gzip, deflate, br',
					// 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
					// 'Connection' => 'keep-alive',
				],
				'json' => [
					"trx_code" => $order[0]->ord_code,
					"drv_name" => $order[0]->drv_name,
					"pickup_zone_title" => $order[0]->pck_name,
					"pickup_zone_addr" => $order[0]->pck_addr,
					"drop_zone_title" => $order[0]->drop_name,
					"drop_zone_addr" => $order[0]->drop_addr,
					"pocket_total" => 'Rp'.number_format($historys[0]->pocket_total, 0, ',', '.'),
					"bank_name" => $order[0]->drv_bank_name,
					"bank_code" => $order[0]->drv_bank_code,
					"bank_branch_name" => $order[0]->drv_bank_branch_name ?? '',
					"bank_acc_name" => $order[0]->drv_bank_acc_name,
					"bank_acc_no" => $order[0]->drv_bank_acc_number,
					"admins" => $admins_data
				],
			]);
			if ($respNode->getStatusCode() != 200) {
				DB::rollBack();
				$apiResp = Responses::bad_request('gagal mengirim email ke finance');
				return (new Response($apiResp, $apiResp['meta']['code']));
			}
			$body = json_decode($respNode->getBody()->getContents());
			
			$apiResp = Responses::success('Berhasil transfer ulang');
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}
}
