<?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\Drivers;
use App\Models\Vehicles;
use App\Models\Orders;
use App\Models\OrdersPickups;
use App\Models\OrdersDrops;
use App\Models\OrdersClients;
use App\Models\OrdersItems;
use App\Models\OrdersAItems;
use App\Models\OrdersRates;
use App\Models\OrdersVendors;
use App\Models\OrdersDrivers;
use App\Models\OrdersVehicles;
use App\Models\OrdersInsurances;
use App\Models\OrdersAccidents;
use App\Models\Zone;
use App\Models\ConfRates;
use App\Models\ConfTruckTypes;
use App\Models\Clients;
use App\Models\Tracks;
use App\Models\Insurances;
use App\Models\Finance;
use App\Models\OrdersInvoices;
use App\Models\OrdersTermins;
use App\Models\OrdersPckDrop;
use App\Models\OrdersPockets;
use App\Models\OrdersCheckpoints;
use App\Models\OrdersDriversUploads;
use App\Models\PocketMoney;
use App\Models\Checkpoints;
use App\Models\UnitTypes;
use App\Models\DrvPhoneDevices;
use App\Models\OrdersLogsTf;
use App\Models\Dana;
use Barryvdh\DomPDF\Facade\Pdf;
use Jurosh\PDFMerge\PDFMerger;

class TransactionController extends Controller
{
    /**
     * VIEW
     */
    public function view_user_vendor_transaction_bid_order(Request $req)
    {
        /**
         * Validate Token
         * Do Login
         * Redirect to route('view_user_vendor_transaction_new_order') . '?code=' . $order_code
         */
        // return Str::uuid()->toString();
        // return (new Nanoid())->generateId(36);

        // test uniq the random code
        // https://blog.bitsrc.io/why-is-nanoid-replacing-uuid-1b5100e62ed2
        // $tokens = [];
        // for ($i=0; $i<1000; $i++) {
        // 	// $token = Str::uuid()->toString();
        // 	$token = (new Nanoid())->generateId(36);
        // 	foreach ($tokens as $tkn) {
        // 		if ($tkn === $token) {
        // 			dd('same');
        // 		}
        // 	}
        // 	$tokens[] = $token;
        // }
        // dd('stop');
        $now = time();
        $input = [
            "token" => $req->token,
        ];
        $rulesInput = [
            "token" => "required|string|max:100",
        ];
        // validasi input
        $isValidInput = Validator::make($input, $rulesInput);
        if (!$isValidInput->passes()) {
            return redirect(route("login"));
        }

        $ord_vdr = OrdersVendors::getByBidToken($req->token);
        if (count($ord_vdr) < 1) {
            return redirect(route("login"));
        }

        Auth::loginUsingId($ord_vdr[0]->vdr_id);
        return redirect(route("view_user_vendor_transaction_new_order") . "?code=" . $ord_vdr[0]->ord_code);
    }

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

        $filter = [
            "code" => $req->ord_code,
            "get_pic_zone" => 1,
            "get_client_pt" => 1,
            "get_stts_checker" => 1,
        ];
        $order = Orders::showOrder($filter);
        if (count($order) < 1) {
            return abort(404, "order not found");
        }

        $filter = [];
        $filter["get_not_deleted"] = 1;

        $items = OrdersItems::getsByOrdId($order[0]->ord_id, $filter);
        if (count($items) < 1) {
            $apiResp = Responses::not_found("order not found");
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }

        $pdf = PDF::loadView("menu_v1._printDeliveryOrder", [
            "order" => $order[0],
            "items" => $items,
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("delivery_order.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }

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

        $filter = [
            "code" => $req->ord_code,
            "get_pic_zone" => 1,
            "get_client_pt" => 1,
            "get_stts_checker" => 1,
        ];
        $order = Orders::showOrder($filter);
        if (count($order) < 1) {
            return abort(404, "order not found");
        }

        $filter = [];
        $filter["get_not_deleted"] = 1;

        $items = OrdersItems::getsByOrdId($order[0]->ord_id, $filter);
        if (count($items) < 1) {
            $apiResp = Responses::not_found("order not found");
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }

        $pdf = PDF::loadView("menu_v1._printInvoiceClient", [
            "order" => $order[0],
            "items" => $items,
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("invoice_client.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }

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

        $filter = [
            "code" => $req->ord_code,
            "get_pic_zone" => 1,
            "get_client_pt" => 1,
            "get_stts_checker" => 1,
        ];
        $order = Orders::showOrder($filter);
        if (count($order) < 1) {
            return abort(404, "order not found");
        }

        $filter = [];
        $filter["get_not_deleted"] = 1;

        $items = OrdersItems::getsByOrdId($order[0]->ord_id, $filter);
        if (count($items) < 1) {
            $apiResp = Responses::not_found("order not found");
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }

        $pdf = PDF::loadView("menu_v1._printPayoutVendor", [
            "order" => $order[0],
            "items" => $items,
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("payout_vendor.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }

    protected function one_page_one_doc(
        $imgPathFile = "",
        $pdfPath = "",
        $pdfTitle = "",
        $imgName = "",
        $outputPdfFile = ""
    ) {
        if (empty($imgPathFile)) {
            return false;
        }
        if (strpos($imgPathFile, ".pdf") !== false) {
            return $imgPathFile;
        } else {
            $imgAry = [];
            if (strpos($imgPathFile, "only_title") !== false) {
                $imgAry[] = [
                    "name" => $imgName,
                ];
            } else {
                $imgAry[] = [
                    "name" => $imgName,
                    "path" => $imgPathFile,
                ];
            }
            $pdf = PDF::loadView("menu_v1.reports._onePageOneImg", [
                "title" => $pdfTitle,
                "imgs" => $imgAry,
            ]);
            Storage::disk("local")->put("public/" . $pdfPath . $outputPdfFile . ".pdf", $pdf->output());
            return $pdfPath . $outputPdfFile . ".pdf";
        }
    }

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

            $filter = [
                "code" => $req->ord_code,
                "get_stts_checker" => 1,
                "get_checker_data" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                return abort(404, "order not found");
            }

            $pdfPath = "";
            foreach (array_slice(explode("/", $order[0]->ord_pck_seal_img), 0, -1) as $k => $r) {
                $pdfPath .= "$r/";
            }

            $pdfMerge = new PDFMerger();
            $availToMergers = [];

            if (strpos($order[0]->ord_pck_seal_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Penjemputan",
                    "Foto Seal",
                    "ord_pck_seal_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_pck_seal_img,
                $pdfPath,
                "Data Penjemputan",
                "Foto Seal",
                "ord_pck_seal_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            if (strpos($order[0]->ord_pck_drv_armd_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Penjemputan",
                    "Foto Pengemudi + Armada",
                    "ord_pck_drv_armd_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_pck_drv_armd_img,
                $pdfPath,
                "Data Penjemputan",
                "Foto Pengemudi + Armada",
                "ord_pck_drv_armd_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            if (strpos($order[0]->ord_pck_nopol_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Penjemputan",
                    "Nomor Polisi Kendaraan",
                    "ord_pck_nopol_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_pck_nopol_img,
                $pdfPath,
                "Data Penjemputan",
                "Nomor Polisi Kendaraan",
                "ord_pck_nopol_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            $ord_pck_docs_client_img = json_decode($order[0]->ord_pck_docs_client_img);
            $order[0]->ord_pck_docs_client_imgs = [];
            foreach ($ord_pck_docs_client_img as $i => $client_img) {
                if (strpos($client_img, ".pdf") !== false) {
                    $onePagePdf = $this->one_page_one_doc(
                        "only_title",
                        $pdfPath,
                        "Data Penjemputan",
                        "Dokumen Kelengkapan dari Client",
                        "ord_pck_doc_client_img_" . $i
                    );
                    if ($onePagePdf) {
                        $availToMergers[] = $onePagePdf;
                    }
                }
                $onePagePdf = $this->one_page_one_doc(
                    $client_img,
                    $pdfPath,
                    "Data Penjemputan",
                    "Dokumen Kelengkapan dari Client",
                    "ord_pck_doc_client_img_" . $i
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }

            if (strpos($order[0]->ord_pck_seal_install_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Penjemputan",
                    "Foto Pemasangan Seal",
                    "ord_pck_seal_install_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_pck_seal_install_img,
                $pdfPath,
                "Data Penjemputan",
                "Foto Pemasangan Seal",
                "ord_pck_seal_install_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            if (strpos($order[0]->ord_pck_goods_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Penjemputan",
                    "Foto Barang",
                    "ord_pck_goods_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_pck_goods_img,
                $pdfPath,
                "Data Penjemputan",
                "Foto Barang",
                "ord_pck_goods_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            foreach ($availToMergers as $key => $row) {
                // Storage::disk('local')->get('public/'.$row);
                $pdfMerge->addPdf(storage_path("app/public/" . $row), "all", "vertical");
            }

            if (count($availToMergers) > 0) {
                $pdfMerge->merge(
                    "file",
                    storage_path("app/public/" . $pdfPath . "download_report_pickup.pdf")
                );
            }

            return response()->file(storage_path("app/public/" . $pdfPath . "download_report_pickup.pdf"));
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return abort(500, $apiResp["meta"]["message"]);
        }
    }
    // without merge pdf
    public function view_transactions_download_report_pickup_bak1(Request $req)
    {
        // try {
        $now = time();
        $input = [
            "ord_code" => $req->ord_code,
        ];
        $rulesInput = [
            "ord_code" => "required|numeric",
        ];
        // validasi input
        $isValidInput = Validator::make($input, $rulesInput);
        if (!$isValidInput->passes()) {
            return abort(403, $isValidInput->messages()->first());
        }

        $filter = [
            "code" => $req->ord_code,
            "get_stts_checker" => 1,
            "get_checker_data" => 1,
        ];
        $order = Orders::showOrder($filter);
        if (count($order) < 1) {
            return abort(404, "order not found");
        }

        // $ord_pck_seal_img_size = getimagesize(__DIR__.'/../../../storage/app/public/'.$order[0]->ord_pck_seal_img);
        // $order[0]->ord_pck_seal_img_width = $ord_pck_seal_img_size[0];
        // $order[0]->ord_pck_seal_img_height = $ord_pck_seal_img_size[1];

        // $ord_pck_drv_armd_img_size = getimagesize(__DIR__.'/../../../storage/app/public/'.$order[0]->ord_pck_drv_armd_img);
        // $order[0]->ord_pck_drv_armd_img_width = $ord_pck_drv_armd_img_size[0];
        // $order[0]->ord_pck_drv_armd_img_height = $ord_pck_drv_armd_img_size[1];

        $order[0]->ord_pck_docs_client_imgs = [];
        foreach (json_decode($order[0]->ord_pck_docs_client_img) as $i => $client_img) {
            // $client_img_size = getimagesize(__DIR__.'/../../../storage/app/public/'.$order[0]->ord_pck_drv_armd_img);
            $order[0]->ord_pck_docs_client_imgs[$i] = [
                "img" => $client_img,
                // 'width' => $client_img_size[0],
                // 'height' => $client_img_size[1],
            ];
        }

        // if ($order[0]->ord_pck_seal_install_img) {
        // 	$ord_pck_seal_install_img_size = getimagesize(__DIR__.'/../../../storage/app/public/'.$order[0]->ord_pck_seal_install_img);
        // 	$order[0]->ord_pck_seal_install_img_width = $ord_pck_seal_install_img_size[0];
        // 	$order[0]->ord_pck_seal_install_img_height = $ord_pck_seal_install_img_size[1];
        // }

        // if ($order[0]->ord_pck_goods_img) {
        // 	$ord_pck_goods_img_size = getimagesize(__DIR__.'/../../../storage/app/public/'.$order[0]->ord_pck_goods_img);
        // 	$order[0]->ord_pck_goods_img_width = $ord_pck_goods_img_size[0];
        // 	$order[0]->ord_pck_goods_img_height = $ord_pck_goods_img_size[1];
        // }

        $pdf = PDF::loadView("menu_v1._printReportPickup", [
            "order" => $order[0],
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("laporan_penjemputan.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }

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

            $filter = [
                "code" => $req->ord_code,
                "get_stts_checker" => 1,
                "get_checker_data" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                return abort(404, "order not found");
            }

            $pdfPath = "";
            foreach (array_slice(explode("/", $order[0]->ord_drop_arrived_img), 0, -1) as $k => $r) {
                $pdfPath .= "$r/";
            }

            $pdfMerge = new PDFMerger();
            $availToMergers = [];

            if (strpos($order[0]->ord_drop_arrived_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Pengantaran",
                    "Foto mobil tiba di tujuan",
                    "ord_drop_arrived_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_drop_arrived_img,
                $pdfPath,
                "Data Pengantaran",
                "Foto mobil tiba di tujuan",
                "ord_drop_arrived_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            if (strpos($order[0]->ord_drop_handover_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Pengantaran",
                    "Foto serah terima",
                    "ord_drop_handover_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_drop_handover_img,
                $pdfPath,
                "Data Pengantaran",
                "Foto serah terima",
                "ord_drop_handover_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            if (strpos($order[0]->ord_drop_do_ttd_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Pengantaran",
                    "Foto DO yg sudah di TTD",
                    "ord_drop_do_ttd_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_drop_do_ttd_img,
                $pdfPath,
                "Data Pengantaran",
                "Foto DO yg sudah di TTD",
                "ord_drop_do_ttd_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            if (strpos($order[0]->ord_drop_spk_img, ".pdf") !== false) {
                $onePagePdf = $this->one_page_one_doc(
                    "only_title",
                    $pdfPath,
                    "Data Pengantaran",
                    "Foto surat jalan di TTD",
                    "ord_drop_spk_img"
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }
            $onePagePdf = $this->one_page_one_doc(
                $order[0]->ord_drop_spk_img,
                $pdfPath,
                "Data Pengantaran",
                "Foto surat jalan di TTD",
                "ord_drop_spk_img"
            );
            if ($onePagePdf) {
                $availToMergers[] = $onePagePdf;
            }

            foreach ($availToMergers as $key => $row) {
                // Storage::disk('local')->get('public/'.$row);
                $pdfMerge->addPdf(storage_path("app/public/" . $row), "all", "vertical");
            }

            if (count($availToMergers) > 0) {
                $pdfMerge->merge("file", storage_path("app/public/" . $pdfPath . "download_report_drop.pdf"));
            }

            return response()->file(storage_path("app/public/" . $pdfPath . "download_report_drop.pdf"));
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return abort(500, $apiResp["meta"]["message"]);
        }
    }
    // without merge pdf
    public function view_transactions_download_report_drop_bak1(Request $req)
    {
        // try {
        $now = time();
        $input = [
            "ord_code" => $req->ord_code,
        ];
        $rulesInput = [
            "ord_code" => "required|numeric",
        ];
        // validasi input
        $isValidInput = Validator::make($input, $rulesInput);
        if (!$isValidInput->passes()) {
            return abort(403, $isValidInput->messages()->first());
        }

        $filter = [
            "code" => $req->ord_code,
            "get_stts_checker" => 1,
            "get_checker_data" => 1,
        ];
        $order = Orders::showOrder($filter);
        if (count($order) < 1) {
            return abort(404, "order not found");
        }

        $pdf = PDF::loadView("menu_v1._printReportDrop", [
            "order" => $order[0],
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("laporan_pengantaran.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }

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

            $filter = [
                "code" => $req->ord_code,
                "get_stts_checker" => 1,
                "get_checker_data" => 1,
                "get_accidents" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                return abort(404, "order not found");
            }

            $pdfPath = "";
            foreach (array_slice(explode("/", $order[0]->ord_pck_seal_img), 0, -1) as $k => $r) {
                $pdfPath .= "$r/";
            }

            $pdfMerge = new PDFMerger();
            $availToMergers = [];

            $pdf = PDF::loadView("menu_v1.reports._printReportAcdntText", [
                "title" => "Data Kecelakaan",
                "order" => $order[0],
            ]);
            Storage::disk("local")->put("public/" . $pdfPath . "printReportAcdntText.pdf", $pdf->output());
            $availToMergers[] = $pdfPath . "printReportAcdntText.pdf";

            $ord_acdnt_imgs = json_decode($order[0]->ord_acdnt_imgs);
            foreach ($ord_acdnt_imgs as $i => $client_img) {
                if (strpos($client_img, ".pdf") !== false) {
                    $onePagePdf = $this->one_page_one_doc(
                        "only_title",
                        $pdfPath,
                        "Data Kecelakaan",
                        "Foto Pendukung",
                        "ord_acdnt_img_" . $i
                    );
                    if ($onePagePdf) {
                        $availToMergers[] = $onePagePdf;
                    }
                }
                $onePagePdf = $this->one_page_one_doc(
                    $client_img,
                    $pdfPath,
                    "Data Kecelakaan",
                    "Foto Pendukung",
                    "ord_acdnt_img_" . $i
                );
                if ($onePagePdf) {
                    $availToMergers[] = $onePagePdf;
                }
            }

            foreach ($availToMergers as $key => $row) {
                // Storage::disk('local')->get('public/'.$row);
                $pdfMerge->addPdf(storage_path("app/public/" . $row), "all", "vertical");
            }

            if (count($availToMergers) > 0) {
                $pdfMerge->merge(
                    "file",
                    storage_path("app/public/" . $pdfPath . "download_report_acdnt.pdf")
                );
            }

            return response()->file(storage_path("app/public/" . $pdfPath . "download_report_acdnt.pdf"));
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return abort(500, $apiResp["meta"]["message"]);
        }
    }
    // without merge pdf
    public function view_transactions_download_report_acdnt_bak1(Request $req)
    {
        // try {
        $now = time();
        $input = [
            "ord_code" => $req->ord_code,
        ];
        $rulesInput = [
            "ord_code" => "required|numeric",
        ];
        // validasi input
        $isValidInput = Validator::make($input, $rulesInput);
        if (!$isValidInput->passes()) {
            return abort(403, $isValidInput->messages()->first());
        }

        $filter = [
            "code" => $req->ord_code,
            "get_stts_checker" => 1,
            "get_checker_data" => 1,
        ];
        $order = Orders::showOrder($filter);
        if (count($order) < 1) {
            return abort(404, "order not found");
        }

        $pdf = PDF::loadView("menu_v1._printReportAcdnt", [
            "order" => $order[0],
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("laporan_pengantaran.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }

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

        $codes = explode(",", $req->ord_code);
        $limit = count($codes);
        if ($limit > 2) {
            return redirect(route("view_transactions"));
        }
        $filter = [
            "codes" => $codes,
            "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,
            "group_by" => "ord.id",
            "limit" => $limit,
        ];
        $orders = Orders::showOrder($filter);
        if (count($orders) < 1) {
            return abort(404, "order not found");
        }
        $bladeViewOrders = [];
        foreach ($orders as $iOrd => $order) {
            // get multiple point (pick,drop)

            $_filter = [
                "id" => $order->ord_id,
                "get_pic_zone" => 1,
                "limit" => $order->drop_total,
            ];

            if (isset($req->point_id)) {
                $_filter["point_id"] = $req->point_id;
            }

            $adtPoints = Orders::getPoints($_filter);
            if (isset($req->point_id) == false) {
                // dd($adtPoints);
                array_splice($adtPoints, 0, 1);
            }

            $orders[$iOrd]->adtPoints = $adtPoints;

            // formated for blade views
            $tmpBladeView = clone $order;
            if ($order->ord_pck_docs_client_img) {
                $tmpBladeView->ord_pck_docs_client_img = json_decode($order->ord_pck_docs_client_img);
            }
            // if ($order->ord_acdnt_imgs) $tmpBladeView->ord_acdnt_imgs = json_decode($order->ord_acdnt_imgs);
            $bladeViewOrders[] = clone $tmpBladeView;
        }
        // clients/25/logo_1720525752.jpeg

        $client = DB::table("t_orders as to")
            ->leftJoin("t_orders_clients as toc", "toc.ord_id", "to.id")
            ->leftJoin("t_clients as tc", "tc.id", "toc.c_pt_id")
            ->where("to.code", $codes)
            ->select("tc.c_name", "tc.c_logo")
            ->first();
        $logo = base_path() . "/public/storage/" . $client->c_logo;

        $_view = isset($req->point_id) ? "menu_v1._printSPKSingle" : "menu_v1._printSPK";

        $pdf = PDF::loadView($_view, [
            "orders" => $orders,
            "client" => $client,
            "logo" => $logo,
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("surat_perintah_kerja.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }
    public function view_transactions_download_summary(Request $req)
    {
        // try {
        $now = time();
        $input = [
            "ord_code" => $req->ord_code,
        ];
        $rulesInput = [
            // 'ord_code' => 'required|numeric', // single
            "ord_code" => "required|string",
        ];
        // validasi input
        $isValidInput = Validator::make($input, $rulesInput);
        if (!$isValidInput->passes()) {
            return abort(403, $isValidInput->messages()->first());
        }

        $codes = explode(",", $req->ord_code);
        $limit = count($codes);
        if ($limit > 2) {
            return redirect(route("view_transactions"));
        }
        $filter = [
            "codes" => $codes,
            "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,
            "group_by" => "ord.id",
            "limit" => $limit,
        ];
        $orders = Orders::showOrder($filter);
        if (count($orders) < 1) {
            return abort(404, "order not found");
        }
        // $bladeViewOrders = [];
        // foreach ($orders as $iOrd => $order) {
        //     // get multiple point (pick,drop)

        //     $_filter = [
        //         "id" => $order->ord_id,
        //         "get_pic_zone" => 1,
        //         "limit" => $order->drop_total,
        //     ];

        //     if (isset($req->point_id)) {
        //         $_filter["point_id"] = $req->point_id;
        //     }

        //     $adtPoints = Orders::getPoints($_filter);
        //     if (isset($req->point_id) == false) {
        //         // dd($adtPoints);
        //         array_splice($adtPoints, 0, 1);
        //     }

        //     $orders[$iOrd]->adtPoints = $adtPoints;

        //     $tmpBladeView = clone $order;
        //     if ($order->ord_pck_docs_client_img) {
        //         $tmpBladeView->ord_pck_docs_client_img = json_decode($order->ord_pck_docs_client_img);
        //     }
        //     $bladeViewOrders[] = clone $tmpBladeView;
        // }
        // dd($orders);

        $client = DB::table("t_orders as to")
            ->leftJoin("t_orders_clients as toc", "toc.ord_id", "to.id")
            ->leftJoin("t_clients as tc", "tc.id", "toc.c_pt_id")
            ->where("to.code", $codes)
            ->select("tc.c_name", "tc.c_logo")
            ->first();
        $logo = base_path() . "/public/storage/" . $client->c_logo;

        $rawData = DB::table("t_orders_pck_drop as topd")
            ->leftJoin("t_orders_pickups as top", "top.id", "topd.pck_id")
            ->leftJoin("t_orders_drops as tod", "tod.id", "topd.drop_id")
            ->where("topd.ord_code", $codes)
            ->selectRaw(
                "topd.id,
                FROM_UNIXTIME(top.set_pck_at, '%d %M %Y') as pck_date,
                FROM_UNIXTIME(top.set_pck_at, '%H:%i:%s') as pck_time,
                top.pck_name,
                top.pck_addr,
                top.pic_name as pck_pic_name,
                top.pic_phone_val as pck_pic_phone,
                tod.drop_name,
                tod.drop_addr,
                tod.pic_name as drp_pic_name,
                tod.pic_phone_val as drp_pic_phone"
            );
        if (isset($req->point_id)) {
            $rawData->where("topd.id", $req->point_id);
        }
        $rawData = $rawData->get();

        foreach ($rawData as $_data) {
            $ehck = DB::table("t_orders_drivers_uploads")
                ->select(
                    "id", //
                    "checklist_name",
                    "checklist_desc",
                    "img",
                    "updt"
                )
                ->where("ord_pck_drop_id", $_data->id)
                ->get();
            $data[] = [
                "id" => $_data->id,
                "pck_date" => $_data->pck_date,
                "pck_time" => $_data->pck_time,
                "pck_name" => $_data->pck_name,
                "pck_addr" => $_data->pck_addr,
                "pck_pic_name" => $_data->pck_pic_name,
                "pck_pic_phone" => $_data->pck_pic_phone,
                "drp_name" => $_data->drop_name,
                "drp_addr" => $_data->drop_addr,
                "drp_pic_name" => $_data->drp_pic_name,
                "drp_pic_phone" => $_data->drp_pic_phone,
                "checklist_array" => $ehck,
            ];
        }
        // $summary = [
        //     "orders" => $orders,
        //     "client" => $client,
        //     "logo" => $logo,
        //     "data" => $data,
        // ];
        // dd($summary);
        // dd($data);
        $pdf = PDF::loadView("menu_v1._printSumarry", [
            "orders" => $orders,
            "client" => $client,
            "logo" => $logo,
            "data" => $data,
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("surat_perintah_kerja.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }
    public function view_transactions_download_spk_single_bak(Request $req)
    {
        // try {
        $now = time();
        $input = [
            "ord_code" => $req->ord_code,
        ];
        $rulesInput = [
            // 'ord_code' => 'required|numeric', // single
            "ord_code" => "required|string",
        ];
        // validasi input
        $isValidInput = Validator::make($input, $rulesInput);
        if (!$isValidInput->passes()) {
            return abort(403, $isValidInput->messages()->first());
        }

        $codes = explode(",", $req->ord_code);
        $limit = count($codes);
        if ($limit > 2) {
            return redirect(route("view_transactions"));
        }

        $filter = [
            "codes" => $codes,
            "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,
        ];
        $orders = Orders::showOrder($filter);
        if (count($orders) < 1) {
            return abort(404, "order not found");
        }
        $adtPoints = Orders::getPoints([
            "id" => $orders[0]->ord_id,
            "limit" => $orders[0]->drop_total,
            "get_pic_zone" => 1,
        ]);
        array_splice($adtPoints, 0, 1);

        $pdf = PDF::loadView("menu_v1._printSPK", [
            "order" => $orders[0],
            "adtPoints" => $adtPoints,
        ]);
        return $pdf->setPaper("a4", "potrait")->stream("surat_perintah_kerja.pdf");
        // } catch (\Exception $e) {
        // 	$apiResp = Responses::error($e->getMessage());
        // 	return abort(500, $apiResp['meta']['message']);
        // }
    }

    /**
     * API
     */

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

            $input = [
                "packing_list" => $req->packing_list,
                // 'weight' => $req->weight,
                // 'cbm' => $req->cbm,
                // 'koli' => $req->koli,
                // 'Item Code' => $req->input('Item Code'),
                // 'Description' => $req->input('Description'),
                // 'Weight (kg)' => $req->input('Weight (kg)'),
                // 'Qty' => $req->input('Qty'),
                // 'Length (cm)' => $req->input('Length (cm)'),
                // 'Wide (cm)' => $req->input('Wide (cm)'),
                // 'Height (cm)' => $req->input('Height (cm)'),
                // 'Volume (m3)' => $req->input('Volume (m3)'),
            ];
            $rulesInput = [
                "packing_list" => "required|array",
                "packing_list.*.Item Code" => "required|string",
                "packing_list.*.Description" => "required|string",
                "packing_list.*.Weight (kg)" => "required|numeric|min:0",
                // 'packing_list.*.Qty' => 'required|numeric|min:0',
                "packing_list.*.Length (cm)" => "required|numeric|min:0",
                "packing_list.*.Wide (cm)" => "required|numeric|min:0",
                "packing_list.*.Height (cm)" => "required|numeric|min:0",
                "packing_list.*.Volume (m3)" => "required|numeric|min:0",
                // 'weight' => 'required',
                // 'cbm' => 'required',
                // 'koli' => 'required',
            ];

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

            $calc_weight = 0;
            // $total_qty = 0;
            $total_koli = 0;
            $calc_length = 0;
            $calc_wide = 0;
            $calc_height = 0;
            $calc_cbm = 0;

            foreach ($req->packing_list as $k => $v) {
                if (count(OrdersItems::getOrderItemByCode($v["Item Code"])) > 0) {
                    $apiResp = Responses::bad_request(
                        "Item Code: " . $v["Item Code"] . " not uniq, please reupload your packing list"
                    );
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                // if (!is_numeric($v['Qty'])) {
                // 	$v['Qty'] = 0;
                // }
                // $total_qty += $v['Qty'];
                if (!is_numeric($v["Weight (kg)"])) {
                    $v["Weight (kg)"] = 0;
                }
                // $calc_weight += $v['Weight (kg)'] * $v['Qty'];
                $calc_weight += $v["Weight (kg)"];
                if (!is_numeric($v["Length (cm)"])) {
                    $v["Length (cm)"] = 0;
                }
                $calc_length += $v["Length (cm)"];
                if (!is_numeric($v["Wide (cm)"])) {
                    $v["Wide (cm)"] = 0;
                }
                $calc_wide += $v["Wide (cm)"];
                if (!is_numeric($v["Height (cm)"])) {
                    $v["Height (cm)"] = 0;
                }
                $calc_height += $v["Height (cm)"];
                if (!is_numeric($v["Volume (m3)"])) {
                    $v["Volume (m3)"] = 0;
                }
                // $calc_volume = ($v['Length (cm)'] * $v['Wide (cm)'] * $v['Height (cm)']) * $v['Qty'];
                $calc_volume = ($v["Length (cm)"] * $v["Wide (cm)"] * $v["Height (cm)"]) / 1000000;
                // $v['Volume (m3)'] = $v['Volume (m3)'] * $v['Qty'];
                $v["Volume (m3)"] = $v["Volume (m3)"];
                if ($calc_volume > $v["Volume (m3)"]) {
                    $calc_cbm += $calc_volume;
                } else {
                    $calc_cbm += $v["Volume (m3)"];
                }

                $total_koli++;
            }

            // if (is_numeric($req->weight)) {
            // 	if ($calc_weight > $req->weight) {
            // 		// $apiResp = Responses::bad_request('The input weight is less than then total weight of the packing list');
            // 		$apiResp = Responses::bad_request('Total weight of the packing list is greater than the input weight, please reupload your packing list');
            // 		return new Response($apiResp, $apiResp['meta']['code']);
            // 	} else {
            // 		$calc_weight = $req->weight;
            // 	}
            // }
            // if (is_numeric($req->cbm)) {
            // 	if ($calc_cbm > $req->cbm) {
            // 		// $apiResp = Responses::bad_request('The input volume is less than then total volume of the packing list');
            // 		$apiResp = Responses::bad_request('Total volume of the packing list is greater than the input volume, please reupload your packing list');
            // 		return new Response($apiResp, $apiResp['meta']['code']);
            // 	} else {
            // 		$calc_cbm = $req->cbm;
            // 	}
            // }
            // if (is_numeric($req->koli)) {
            // 	if ($total_qty > $req->koli) {
            // 		// $apiResp = Responses::bad_request('The input koli is less than then total koli of the packing list');
            // 		$apiResp = Responses::bad_request('Total koli of the packing list is greater than the input koli, please reupload your packing list');
            // 		return new Response($apiResp, $apiResp['meta']['code']);
            // 	} else {
            // 		$total_qty = $total_qty;
            // 	}
            // }
            if ($calc_weight === 0 && $calc_cbm === 0) {
                $apiResp = Responses::bad_request(
                    "You must fill in at least 1 of weight / dimension / volume on packing list."
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $apiResp = Responses::success("packing list valid");
            $apiResp["data"] = [
                "calc_weight" => $calc_weight,
                "calc_cbm" => $calc_cbm,
                // 'total_qty' => $total_qty,
                "total_koli" => $total_koli,
            ];
            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_checkout_v1(Request $req)
    {
        try {
            $now = time();

            $input = [
                "pickup_at" => $req->pickup_at,
                "pickup_zone_id" => $req->pickup_zone_id,
                "drop_zone_id" => $req->drop_zone_id,
                "weight" => $req->weight,
                "cbm" => $req->cbm,
                "koli" => $req->koli,
                "truck_type_id" => $req->truck_type_id,
                "truck_type_name" => $req->truck_type_name,
                "truck_type_weight" => $req->truck_type_weight,
                "truck_type_cbm" => $req->truck_type_cbm,
                "truck_type_koli" => $req->truck_type_koli,
            ];
            $rulesInput = [
                "pickup_at" => "required|integer",
                "pickup_zone_id" => "required|integer",
                "drop_zone_id" => "required|integer",
                "weight" => "nullable",
                "cbm" => "nullable",
                "koli" => "nullable",
                "truck_type_id" => "required|numeric",
                "truck_type_name" => "nullable|string",
                "truck_type_weight" => "nullable",
                "truck_type_cbm" => "nullable",
                "truck_type_koli" => "nullable",
            ];

            // 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 (!is_numeric($req->weight) && !is_numeric($req->cbm) && !is_numeric($req->koli)) {
                $apiResp = Responses::bad_request("You must fill in at least 1 of the packing list.");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if ($req->weight === 0 && $req->cbm === 0 && $req->koli === 0) {
                $apiResp = Responses::bad_request("You must fill in at least 1 of the packing list.");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $pck = Zone::getZoneById($req->pickup_zone_id);
            if (count($pck) < 1) {
                $apiResp = Responses::bad_request("Pickup zone not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($pck[0]->prid == 0) {
                $apiResp = Responses::bad_request(
                    "Pickup zone province not filled, please recheck input province zone"
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $drop = Zone::getZoneById($req->drop_zone_id);
            if (count($drop) < 1) {
                $apiResp = Responses::bad_request("Drop zone not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($drop[0]->ktid == 0) {
                $apiResp = Responses::bad_request(
                    "Drop zone city not filled, please recheck input city zone"
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($drop[0]->kcid == 0) {
                $apiResp = Responses::bad_request(
                    "Drop zone district not filled, please recheck input district zone"
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $rates = ConfRates::getRateByDestDistrict($pck[0]->prid, $drop[0]->kcid);
            if (count($rates) < 1) {
                $rates = ConfRates::getRateByDestCity($pck[0]->prid, $drop[0]->ktid);
            }

            if (count($rates) < 1) {
                $apiResp = Responses::bad_request("No service available going to drop zone");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            // check maximum weight / cbm truck type yang ada sekarang
            $use_price_cbm = 1;
            $use_price_weight = 1;
            if ($req->truck_type_id && $req->truck_type_id != 0) {
                if ($req->truck_type_cbm != 0 && $req->truck_type_cbm > $req->cbm) {
                    $apiResp = Responses::bad_request("Cbm is over load");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                } elseif ($req->truck_type_weight != 0 && $req->truck_type_weight > $req->weight) {
                    $apiResp = Responses::bad_request("Weight is over load");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                } else {
                    $apiResp = Responses::bad_request("Package list is over load");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            } else {
                $truck_types = ConfTruckTypes::listTruckTypesRates(
                    ConfTruckTypes::IS_ACTIVE,
                    ConfRates::LANE_EARTH
                );
                if (count($truck_types) < 1) {
                    $apiResp = Responses::bad_request("No vehicle available");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                $is_tt_overload = 1;
                foreach ($truck_types as $k => $v) {
                    if ($v->max_cbm != 0 && $v->max_cbm < $req->cbm) {
                        $is_tt_overload = 0;
                    } elseif ($v->max_kg != 0 && $v->max_kg < $req->weight) {
                        $is_tt_overload = 0;
                    }
                }
                if (!$is_tt_overload) {
                    $apiResp = Responses::bad_request("Package list is over load");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }

            $client = Clients::getClientById($req->auth->client_group_id);

            $opts = [];
            foreach ($rates as $k => $v) {
                $opt = [
                    "is_best" => 0,
                ];
                if ($k === 0) {
                    $opt["is_best"] = 1;
                }
                $opt["lead_time_id"] = $v->id;
                // $center_time = $v->long_time - $v->fast_time;
                $opt["lead_time"] = $v->long_time;
                $price = 0;
                if (is_numeric($req->cbm) && $req->cbm != 0 && $v->sell_cbm != 0 && $use_price_cbm != 0) {
                    $price = $req->cbm * $v->sell_cbm;
                } else {
                    if (
                        is_numeric($req->weight) &&
                        $req->weight != 0 &&
                        $v->sell_kg != 0 &&
                        $use_price_weight != 0
                    ) {
                        $price = $req->weight * $v->sell_kg;
                    } else {
                        if (is_numeric($req->koli) && $req->koli != 0 && $v->sell_cbm != 0) {
                            $price = $req->koli * Orders::ONE_KG_ONE_CBM * $v->sell_cbm;
                        }
                    }
                }
                if ($price == 0) {
                    $apiResp = Responses::bad_request("No service provided");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                $opt["price"] = $price;
                $opt["real_price"] = $price;
                $opt["disc_price"] = 0;
                $opt["disc_type"] = $client[0]->disc_type;
                $opt["disc_percent"] = 0;
                if ($client[0]->disc_type === Clients::DISC_TYPE_FIX) {
                    $opt["disc_price"] = $client[0]->disc_amount;
                    $opt["price"] = $opt["price"] - $opt["disc_price"];
                } elseif ($client[0]->disc_type === Clients::DISC_TYPE_PERCENT) {
                    $opt["disc_percent"] = $client[0]->disc_amount;
                    $opt["disc_price"] = ($opt["price"] * $client[0]->disc_amount) / 100;
                    $opt["price"] = $opt["price"] - $opt["disc_price"];
                }
                // group by lead_time and sell_price
                $isSame = 0;
                foreach ($opts as $key => $val) {
                    if ($val["price"] == $opt["price"] && $val["lead_time"] == $opt["lead_time"]) {
                        $isSame = 1;
                    }
                }
                if ($isSame === 1) {
                    continue;
                }
                array_push($opts, $opt);
            }

            $apiResp = Responses::success("checkout success");
            $apiResp["data"] = $opts;
            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_checkout_v2(Request $req)
    {
        try {
            // $apiResp = Responses::bad_request("Service on maintenance");
            // return new Response($apiResp, $apiResp["meta"]["code"]);

            // $now = time();

            $input = [
                "pickup_at" => $req->pickup_at,
                "pickup_zone_id" => $req->pickup_zone_id,
                "drop_zone_id" => $req->drop_zone_id,
                // "truck_type_id" => $req->truck_type_id,
                // "truck_type_name" => $req->truck_type_name,
            ];
            $rulesInput = [
                "pickup_at" => "required|integer",
                "pickup_zone_id" => "required|integer",
                "drop_zone_id" => "required|integer",
                // "truck_type_id" => "required|numeric",
                // "truck_type_name" => "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"]);
            }

            $adm_id = 0;
            $crt_type_order = Orders::CRT_TYPE_ORDER_CLIENT;
            if ($req->auth->role === Users::ROLE_ADMIN) {
                $subInput = [
                    "uid" => $req->uid,
                ];
                $rulesSubInput = [
                    "uid" => "required|integer|not_in:0",
                ];

                // validasi subInput
                $isValidInput = Validator::make($subInput, $rulesSubInput);
                if (!$isValidInput->passes()) {
                    $apiResp = Responses::bad_input($isValidInput->messages()->first());
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                $adminAuth = $req->auth;
                $req->auth = Users::getUserById($req->uid)[0];
                $req->auth->uid = $req->auth->id;

                $adm_id = $adminAuth->uid;
                $crt_type_order = Orders::CRT_TYPE_ORDER_ADMIN;
            }

            $pck = Zone::getZoneById($req->pickup_zone_id);
            if (count($pck) < 1) {
                $apiResp = Responses::bad_request("Pickup zone not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($pck[0]->prid == 0) {
                $apiResp = Responses::bad_request(
                    "Pickup zone province not filled, please recheck input province zone"
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $drop = Zone::getZoneById($req->drop_zone_id);
            if (count($drop) < 1) {
                $apiResp = Responses::bad_request("Drop zone not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($drop[0]->ktid == 0) {
                $apiResp = Responses::bad_request(
                    "Drop zone city not filled, please recheck input city zone"
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($drop[0]->kcid == 0) {
                $apiResp = Responses::bad_request(
                    "Drop zone district not filled, please recheck input district zone"
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            // $rates = ConfRates::getRateByDestDistrict($pck[0]->prid, $drop[0]->kcid);
            // // dd($rates);
            // if (count($rates) < 1) {
            //     $rates = ConfRates::getRateByDestCity($pck[0]->prid, $drop[0]->ktid);
            // }

            // if (count($rates) < 1) {
            //     $apiResp = Responses::bad_request("No service available going to drop zone");
            //     return new Response($apiResp, $apiResp["meta"]["code"]);
            // }
            $rates = 0;

            $client = Clients::getClientById($req->auth->client_group_id);

            $check_truck_type = false;
            $ttid = 0;
            if ($req->truck_type_id && $req->truck_type_id != 0) {
                $check_truck_type = true;
                $ttid = (int) $req->truck_type_id;
            }

            $opts = [];
            // foreach ($rates as $k => $v) {
            //     if ($check_truck_type) {
            //         if ($v->vhc_type !== $ttid) {
            //             continue;
            //         }
            //     }

            //     $opt = [
            //         "is_best" => 0,
            //     ];
            //     if ($k === 0) {
            //         $opt["is_best"] = 1;
            //     }
            //     $opt["lead_time_id"] = $v->id;
            //     // $center_time = $v->long_time - $v->fast_time;
            //     $opt["lead_time"] = $v->long_time;
            //     $price = $v->sell_ftl ?? 0;

            //     // TRIGER JIKA HARGA 0
            //     // if ($price < 1) {
            //     //     $apiResp = Responses::bad_request("No service provided");
            //     //     return new Response($apiResp, $apiResp["meta"]["code"]);
            //     // }
            //     $opt["price"] = $price;
            //     $opt["real_price"] = $price;
            //     $opt["disc_price"] = 0;
            //     $opt["disc_type"] = $client[0]->disc_type;
            //     $opt["disc_percent"] = 0;
            //     if ($client[0]->disc_type === Clients::DISC_TYPE_FIX) {
            //         $opt["disc_price"] = $client[0]->disc_amount;
            //         $opt["price"] = $opt["price"] - $opt["disc_price"];
            //     } elseif ($client[0]->disc_type === Clients::DISC_TYPE_PERCENT) {
            //         $opt["disc_percent"] = $client[0]->disc_amount;
            //         $opt["disc_price"] = ($opt["price"] * $client[0]->disc_amount) / 100;
            //         $opt["price"] = $opt["price"] - $opt["disc_price"];
            //     }
            //     // group by lead_time and sell_price
            //     $isSame = 0;
            //     foreach ($opts as $key => $val) {
            //         if ($val["price"] == $opt["price"] && $val["lead_time"] == $opt["lead_time"]) {
            //             $isSame = 1;
            //         }
            //     }
            //     if ($isSame === 1) {
            //         continue;
            //     }
            //     array_push($opts, $opt);
            // }
            // dd(count($opts));
            // if (count($opts) < 1 && $check_truck_type) {
            //     $apiResp = Responses::bad_request("No truck type available going to drop zone");
            //     return new Response($apiResp, $apiResp["meta"]["code"]);
            // }

            $apiResp = Responses::success("checkout success");
            $apiResp["data"] = $opts;

            if ($req->is_insurance === "true") {
                $insurances = Insurances::getInsurancesByRangeBeneficiaryAndActive($req->amt_beneficiary);
                if (count($insurances) < 1) {
                    $apiResp = Responses::bad_request("Total pertangguhan tidak tersedia");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                $apiResp["insurance"] = $insurances[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_create_order_v1(Request $req)
    {
        try {
            $now = time();

            $input = [
                "pickup_at" => $req->pickup_at,
                "pickup_zone_id" => $req->pickup_zone_id,
                "drop_zone_id" => $req->drop_zone_id,
                "weight" => $req->weight,
                "cbm" => $req->cbm,
                "koli" => $req->koli,
                "qty" => $req->qty,
                "packing_list" => $req->packing_list,
                "lead_time" => $req->lead_time,
                "price" => $req->price,
                "real_price" => $req->real_price,
                "disc_price" => $req->disc_price,
                "lead_time_id" => $req->lead_time_id,
                "truck_type_id" => $req->truck_type_id,
                "truck_type_name" => $req->truck_type_name,
                "truck_type_weight" => $req->truck_type_weight,
                "truck_type_cbm" => $req->truck_type_cbm,
                "truck_type_koli" => $req->truck_type_koli,
            ];
            $rulesInput = [
                "pickup_at" => "required|integer",
                "pickup_zone_id" => "required|integer",
                "drop_zone_id" => "required|integer",
                "weight" => "nullable",
                "cbm" => "nullable",
                "koli" => "nullable",
                "qty" => "nullable",
                "packing_list" => "required|array",
                "packing_list.*.Item Code" => "required|string",
                "packing_list.*.Description" => "required|string",
                "packing_list.*.Weight (kg)" => "required|numeric|min:0",
                // 'packing_list.*.Qty' => 'required|numeric|min:0',
                "packing_list.*.Length (cm)" => "required|numeric|min:0",
                "packing_list.*.Wide (cm)" => "required|numeric|min:0",
                "packing_list.*.Height (cm)" => "required|numeric|min:0",
                "packing_list.*.Volume (m3)" => "required|numeric|min:0",
                "lead_time" => "required|numeric",
                "price" => "required|numeric",
                "real_price" => "required|numeric",
                "disc_price" => "required|numeric",
                "lead_time_id" => "required|integer|not_in:0",
                "truck_type_id" => "nullable|numeric",
                "truck_type_name" => "nullable|string",
                "truck_type_weight" => "nullable",
                "truck_type_cbm" => "nullable",
                "truck_type_koli" => "nullable",
            ];

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

            $type_truck_name = $req->truck_type_name;
            if ($req->truck_type_id && $req->truck_type_id != 0) {
                $type_truck_name = $req->truck_type_name;
            } else {
                $type_truck_name = "";
                $req->truck_type_id = 0;
            }

            if (!is_numeric($req->weight)) {
                $req->weight = 0;
            }
            if (!is_numeric($req->cbm)) {
                $req->cbm = 0;
            }
            if (!is_numeric($req->koli)) {
                $req->koli = 0;
            }
            if (!is_numeric($req->qty)) {
                $req->qty = 0;
            }

            $nanoid = new Nanoid();
            $code = $nanoid->formattedId("0123456789", 12);
            $uniqCode = Orders::getOrderByCode($code);
            if (count($uniqCode) > 0) {
                $code = $nanoid->formattedId("0123456789", 12);
                if (count($uniqCode) > 0) {
                    $code = $nanoid->formattedId("0123456789", 12);
                    if (count($uniqCode) > 0) {
                        $code = $nanoid->formattedId("0123456789", 12);
                        $apiResp = Responses::bad_request("code has been used, try again");
                        return new Response($apiResp, $apiResp["meta"]["code"]);
                    }
                }
            }

            $client = Clients::getClientById($req->auth->client_group_id);
            $rate = ConfRates::getRateById($req->lead_time_id);
            $pck = Zone::getZoneById($req->pickup_zone_id);
            // $pck_pic = Clients::getClientById($pck[0]->client_group_id);
            $drop = Zone::getZoneById($req->drop_zone_id);
            // $drop_pic = Clients::getClientById($drop[0]->client_group_id);
            $admins = Users::getUsersActiveByRole(Users::ROLE_ADMIN);

            $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" => "",
                ]);
            }

            DB::beginTransaction();

            $insOrd = [
                "code" => $code,
                "type" => Orders::TYPE_FCL,
                "pck_total" => 1,
                "drop_total" => 1,
                "est_weight" => $req->weight,
                "weight" => $req->weight,
                "est_cbm" => $req->cbm,
                "cbm" => $req->cbm,
                "est_koli" => $req->koli,
                "koli" => $req->koli,
                "est_qty" => $req->qty,
                "qty" => $req->qty,
                "est_lead_time" => $req->lead_time,
                "lead_time" => $req->lead_time,
                "est_price" => $req->price,
                "price" => $req->price,
                "est_real_price" => $req->real_price,
                "real_price" => $req->real_price,
                "est_disc_price" => $req->disc_price,
                "disc_price" => $req->disc_price,
                "est_rate_id" => $req->lead_time_id,
                "rate_id" => $req->lead_time_id,
                "crt" => $now,
                "crt_by" => $req->auth->uid,
                "updt" => $now,
                "updt_by" => $req->auth->uid,
            ];
            $ord_id = Orders::addOrder($insOrd);

            if ($pck[0]->boundary_bounds) {
                // $pck[0]->boundary_bounds = json_encode($pck[0]->boundary_bounds);
            }
            if ($pck[0]->boundary_latlngs) {
                // $pck[0]->boundary_latlngs = json_encode($pck[0]->boundary_latlngs);
            }

            $insPck = [
                "ord_id" => $ord_id,
                "ord_code" => $code,
                "set_pck_at" => $req->pickup_at,
                "stts_pck" => OrdersPickups::STTS_WAIT,
                "pck_id" => $pck[0]->id,
                "pck_name" => $pck[0]->name,
                "pck_desc" => $pck[0]->desc,
                "pck_type" => $pck[0]->type,
                "pck_workflow" => $pck[0]->workflow_type,
                "pck_shiptocode" => $pck[0]->shiptocode,
                "pck_prid" => $pck[0]->prid,
                "pck_ktid" => $pck[0]->ktid,
                "pck_kcid" => $pck[0]->kcid,
                "pck_klid" => $pck[0]->klid,
                "pck_addr" => $pck[0]->fulladdress,
                "pck_cgroup_id" => $pck[0]->client_group_id,
                "pck_cdiv_id" => $pck[0]->client_div_id,
                "pck_cgp_id" => $pck[0]->client_gp_id,
                "pck_hex_color" => $pck[0]->boundary_hex_color,
                "pck_shape" => $pck[0]->boundary_type,
                "pck_radius" => $pck[0]->boundary_radius,
                "pck_bounds" => $pck[0]->boundary_bounds,
                "pck_latlngs" => $pck[0]->boundary_latlngs,
                "pck_points" => $pck[0]->boundary_points,
                // 'pic_name' => $pck_pic[0]->pic_name,
                // 'pic_phone_code' => $pck_pic[0]->pic_phone_code,
                // 'pic_phone_val' => $pck_pic[0]->pic_phone,
                // 'pic_mail' => $pck_pic[0]->pic_mail,
                "pic_name" => $req->auth->first_name,
                "pic_phone_code" => $req->auth->phone_code,
                "pic_phone_val" => $req->auth->phone,
                "pic_mail" => $req->auth->email,
                "est_weight" => $req->weight,
                "weight" => $req->weight,
                "est_cbm" => $req->cbm,
                "cbm" => $req->cbm,
                "est_koli" => $req->koli,
                "koli" => $req->koli,
                "est_qty" => $req->qty,
                "qty" => $req->qty,
            ];

            $pck_id = OrdersPickups::add($insPck);

            if ($drop[0]->boundary_bounds) {
                // $drop[0]->boundary_bounds = json_encode($drop[0]->boundary_bounds);
            }
            if ($drop[0]->boundary_latlngs) {
                // $drop[0]->boundary_latlngs = json_encode($drop[0]->boundary_latlngs);
            }

            $insDrop = [
                "ord_id" => $ord_id,
                "ord_code" => $code,
                "stts_drop" => OrdersDrops::STTS_WAIT,
                "drop_id" => $drop[0]->id,
                "drop_name" => $drop[0]->name,
                "drop_desc" => $drop[0]->desc,
                "drop_type" => $drop[0]->type,
                "drop_workflow" => $drop[0]->workflow_type,
                "drop_shiptocode" => $drop[0]->shiptocode,
                "drop_prid" => $drop[0]->prid,
                "drop_ktid" => $drop[0]->ktid,
                "drop_kcid" => $drop[0]->kcid,
                "drop_klid" => $drop[0]->klid,
                "drop_addr" => $drop[0]->fulladdress,
                "drop_cgroup_id" => $drop[0]->client_group_id,
                "drop_cdiv_id" => $drop[0]->client_div_id,
                "drop_cgp_id" => $drop[0]->client_gp_id,
                "drop_hex_color" => $drop[0]->boundary_hex_color,
                "drop_shape" => $drop[0]->boundary_type,
                "drop_radius" => $drop[0]->boundary_radius,
                "drop_bounds" => $drop[0]->boundary_bounds,
                "drop_latlngs" => $drop[0]->boundary_latlngs,
                "drop_points" => $drop[0]->boundary_points,
                // 'pic_name' => $drop_pic[0]->pic_name,
                // 'pic_phone_code' => $drop_pic[0]->pic_phone_code,
                // 'pic_phone_val' => $drop_pic[0]->pic_phone,
                // 'pic_mail' => $drop_pic[0]->pic_mail,
                "pic_name" => $req->auth->first_name,
                "pic_phone_code" => $req->auth->phone_code,
                "pic_phone_val" => $req->auth->phone,
                "pic_mail" => $req->auth->email,
                "est_weight" => $req->weight,
                "weight" => $req->weight,
                "est_cbm" => $req->cbm,
                "cbm" => $req->cbm,
                "est_koli" => $req->koli,
                "koli" => $req->koli,
                "est_qty" => $req->qty,
                "qty" => $req->qty,
            ];
            $drop_id = OrdersDrops::add($insDrop);

            $insClient = [
                "ord_id" => $ord_id,
                "ord_code" => $code,
                "c_id" => $req->auth->uid,
                "c_name" => $req->auth->first_name,
                "c_phone_code" => $req->auth->phone_code,
                "c_phone_val" => $req->auth->phone,
                "c_mail" => $req->auth->email,
                "c_addr" => $req->auth->fulladdress,
                "c_disc_type" => $client[0]->disc_type,
                "c_disc_amount" => $client[0]->disc_amount,
                "c_pt_id" => $client[0]->id,
                "c_pt_div_id" => $req->auth->client_div_id,
                "c_pt_gp_id" => $req->auth->client_gp_id,
                "c_pt_name" => $client[0]->c_name,
                "c_pt_phone_code" => $client[0]->c_phone_code,
                "c_pt_phone_val" => $client[0]->c_phone,
                "c_pt_mail" => $client[0]->c_mail,
                "c_pt_addr" => $client[0]->c_addr_office,
                "c_pt_pic_name" => $client[0]->pic_name,
                "c_pt_pic_phone_code" => $client[0]->pic_phone_code,
                "c_pt_pic_phone_val" => $client[0]->pic_phone,
                "c_pt_pic_mail" => $client[0]->pic_mail,
                "c_pt_pic_addr" => null,
                "prefer_truck_type" => $req->truck_type_id,
            ];
            $ord_client_id = OrdersClients::add($insClient);

            foreach ($req->packing_list as $k => $v) {
                $insItems = [
                    "ord_id" => $ord_id,
                    "ord_code" => $code,
                    "pck_id" => $pck_id,
                    "drop_id" => $drop_id,
                    "item_code" => $v["Item Code"],
                    "desc" => $v["Description"],
                    "unit_weight" => OrdersItems::DEFAULT_WEIGHT_UNIT,
                    "weight" => $v["Weight (kg)"],
                    "unit_dimension" => OrdersItems::DEFAULT_DIMENSION_UNIT,
                    // 'qty' => $v['Qty'] ?? 0,
                    "length" => $v["Length (cm)"],
                    "wide" => $v["Wide (cm)"],
                    "height" => $v["Height (cm)"],
                    "volume" => $v["Volume (m3)"],
                    "crt" => $now,
                ];
                OrdersItems::add($insItems);
            }

            $insRate = [
                "ord_id" => $ord_id,
                "ord_code" => $code,
                "rate_id" => $rate[0]->id,
                "rate_code" => $rate[0]->code,
                "origin_prov" => $rate[0]->origin_prov,
                "origin_city" => $rate[0]->origin_city,
                "origin_district" => $rate[0]->origin_district,
                "origin_village" => $rate[0]->origin_village,
                "lane" => $rate[0]->lane,
                "dest_prov" => $rate[0]->dest_prov,
                "dest_city" => $rate[0]->dest_city,
                "dest_district" => $rate[0]->dest_district,
                "dest_village" => $rate[0]->dest_village,
                "fast_time" => $rate[0]->fast_time,
                "long_time" => $rate[0]->long_time,
                "unit_time" => $rate[0]->unit_time,
                "sell_kg" => $rate[0]->sell_kg,
                "buy_kg" => $rate[0]->buy_kg,
                "margin_kg" => $rate[0]->margin_kg,
                "percent_kg" => $rate[0]->percent_kg,
                "sell_cbm" => $rate[0]->sell_cbm,
                "buy_cbm" => $rate[0]->buy_cbm,
                "margin_cbm" => $rate[0]->margin_cbm,
                "percent_cbm" => $rate[0]->percent_cbm,
                "vdr_id" => $rate[0]->vdr_id,
                "vhc_type" => $rate[0]->vhc_type,
            ];
            OrdersRates::add($insRate);

            $url = env("API_URL_NODE") . "/order/create";
            $guzReq = new GuzzleClient();
            $respNode = $guzReq->request("POST", $url, [
                "headers" => [
                    "Host" => $_SERVER["SERVER_ADDR"],
                    "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" => $code,
                    "trx_at" => $now,
                    "client_id" => $req->auth->uid,
                    "client_name" => $req->auth->first_name,
                    "client_phone" =>
                        $req->auth->phone_code . " " . implode(" ", str_split($req->auth->phone, 4)),
                    "client_mail" => $req->auth->email,
                    "client_addr" => "",
                    "client_prefer_type_truck" => $type_truck_name,
                    "weight" => $req->weight,
                    "cbm" => $req->cbm,
                    "koli" => $req->koli,
                    "pickup_zone_title" => $pck[0]->name,
                    "pickup_zone_addr" => $pck[0]->fulladdress,
                    "pickup_at" => $req->pickup_at,
                    "drop_zone_title" => $drop[0]->name,
                    "drop_zone_addr" => $drop[0]->fulladdress,
                    "admins" => $admins_data,
                ],
            ]);
            if ($respNode->getStatusCode() != 200) {
                DB::rollBack();
                $apiResp = Responses::bad_request("fail create order 0");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $body = json_decode($respNode->getBody()->getContents());

            $apiResp = Responses::created("success create order");

            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_create_order_v2(Request $req)
    {
        // dd($req->all());
        try {
            // $apiResp = Responses::bad_request("Service on maintenance");
            // return new Response($apiResp, $apiResp["meta"]["code"]);
            $now = time();

            $input = [
                "pickup_at" => $req->pickup_at,
                "pickup_zone_id" => $req->pickup_zone_id,
                "drop_zone_id" => $req->drop_zone_id,
                // "lead_time" => $req->lead_time,
                // "price" => $req->price,
                // "real_price" => $req->real_price,
                // "disc_price" => $req->disc_price,
                // "lead_time_id" => $req->lead_time_id,
                "vehicle_id" => $req->vehicle_id,
                "vehicle_name" => $req->vehicle_name,
                "driver_id" => $req->driver_id,
                "driver_name" => $req->driver_name,
            ];
            $rulesInput = [
                "pickup_at" => "required|integer",
                "pickup_zone_id" => "required|integer",
                "drop_zone_id" => "required|integer",
                // "lead_time" => "required|numeric",
                // "price" => "required|numeric",
                // "real_price" => "required|numeric",
                // "disc_price" => "required|numeric",
                // "lead_time_id" => "required|integer|not_in:0",
                "vehicle_id" => "nullable|numeric",
                "vehicle_name" => "nullable|string",
                "driver_id" => "nullable|numeric",
                "driver_name" => "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"]);
            }

            $adm_id = 0;
            $crt_type_order = Orders::CRT_TYPE_ORDER_CLIENT;
            if ($req->auth->role === Users::ROLE_ADMIN) {
                $subInput = [
                    "uid" => $req->uid,
                ];
                $rulesSubInput = [
                    "uid" => "required|integer|not_in:0",
                ];

                // validasi subInput
                $isValidInput = Validator::make($subInput, $rulesSubInput);
                if (!$isValidInput->passes()) {
                    $apiResp = Responses::bad_input($isValidInput->messages()->first());
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                $adminAuth = $req->auth;
                $req->auth = Users::getUserById($req->uid)[0];
                $req->auth->uid = $req->auth->id;

                $adm_id = $adminAuth->uid;
                $crt_type_order = Orders::CRT_TYPE_ORDER_ADMIN;
            }

            $vehicle_name = $req->vehicle_name;
            if ($req->vehicle_id && $req->vehicle_id != 0) {
                $vehicle_name = $req->vehicle_name;
            } else {
                $vehicle_name = "";
                $req->truck_type_id = 0;
            }

            $nanoid = new Nanoid();
            $code = $nanoid->formattedId("0123456789", 12);
            $doWhile = true;
            do {
                $uniqCode = Orders::getOrderByCode($code);
                if (count($uniqCode) > 0) {
                    $code = $nanoid->formattedId("0123456789", 12);
                } else {
                    $doWhile = false;
                }
            } while ($doWhile);

            $client = Clients::getClientById($req->auth->client_group_id);
            // $rate = ConfRates::getRateById(0);
            $pck = Zone::getZoneById($req->pickup_zone_id);
            // $pck_pic = Clients::getClientById($pck[0]->client_group_id);
            $drop = Zone::getZoneById($req->drop_zone_id);
            // $drop_pic = Clients::getClientById($drop[0]->client_group_id);
            $admins = Users::getUsersActiveByRole(Users::ROLE_ADMIN);
            $insurance = [];
            if ($req->is_insurance === "true") {
                $insurance = Insurances::getInsuranceById($req->insurance_id);
                if (count($insurance) < 1) {
                    $apiResp = Responses::bad_request("Insurance not found");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }

            $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" => "",
                ]);
            }
            DB::beginTransaction();

            $insOrd = [
                "code" => $code,
                "type" => Orders::TYPE_FCL,
                "pck_total" => 1,
                "drop_total" => 1,
                "est_lead_time" => 0,
                "lead_time" => 0,
                "est_price" => 0,
                "price" => 0,
                "est_real_price" => 0,
                "real_price" => 0,
                "est_disc_price" => 0,
                "disc_price" => 0,
                "est_rate_id" => 0,
                "rate_id" => 0,
                "crt_type_order" => $crt_type_order,
                "crt" => $now,
                "crt_by" => $req->auth->uid,
                "crt_adm_by" => $adm_id,
                "updt" => $now,
                "updt_by" => $req->auth->uid,
            ];
            $ord_id = Orders::addOrder($insOrd);

            $insPck = [
                "ord_id" => $ord_id,
                "ord_code" => $code,
                "set_pck_at" => $req->pickup_at,
                "stts_pck" => OrdersPickups::STTS_WAIT,
                "pck_id" => $pck[0]->id,
                "pck_name" => $pck[0]->name,
                "pck_desc" => $pck[0]->desc,
                "pck_type" => $pck[0]->type,
                "pck_workflow" => $pck[0]->workflow_type,
                "pck_shiptocode" => $pck[0]->shiptocode,
                "pck_prid" => $pck[0]->prid,
                "pck_ktid" => $pck[0]->ktid,
                "pck_kcid" => $pck[0]->kcid,
                "pck_klid" => $pck[0]->klid,
                "pck_addr" => $pck[0]->fulladdress,
                "pck_cgroup_id" => $pck[0]->client_group_id,
                "pck_cdiv_id" => $pck[0]->client_div_id,
                "pck_cgp_id" => $pck[0]->client_gp_id,
                "pck_hex_color" => $pck[0]->boundary_hex_color,
                "pck_shape" => $pck[0]->boundary_type,
                "pck_radius" => $pck[0]->boundary_radius,
                "pck_bounds" => $pck[0]->boundary_bounds,
                "pck_latlngs" => $pck[0]->boundary_latlngs,
                "pck_points" => $pck[0]->boundary_points,
                // 'pic_name' => $pck_pic[0]->pic_name,
                // 'pic_phone_code' => $pck_pic[0]->pic_phone_code,
                // 'pic_phone_val' => $pck_pic[0]->pic_phone,
                // 'pic_mail' => $pck_pic[0]->pic_mail,
                "pic_name" => $req->auth->first_name,
                "pic_phone_code" => $req->auth->phone_code,
                "pic_phone_val" => $req->auth->phone,
                "pic_mail" => $req->auth->email,
            ];

            $pck_id = OrdersPickups::add($insPck);

            $insDrop = [
                "ord_id" => $ord_id,
                "ord_code" => $code,
                "stts_drop" => OrdersDrops::STTS_WAIT,
                "drop_id" => $drop[0]->id,
                "drop_name" => $drop[0]->name,
                "drop_desc" => $drop[0]->desc,
                "drop_type" => $drop[0]->type,
                "drop_workflow" => $drop[0]->workflow_type,
                "drop_shiptocode" => $drop[0]->shiptocode,
                "drop_prid" => $drop[0]->prid,
                "drop_ktid" => $drop[0]->ktid,
                "drop_kcid" => $drop[0]->kcid,
                "drop_klid" => $drop[0]->klid,
                "drop_addr" => $drop[0]->fulladdress,
                "drop_cgroup_id" => $drop[0]->client_group_id,
                "drop_cdiv_id" => $drop[0]->client_div_id,
                "drop_cgp_id" => $drop[0]->client_gp_id,
                "drop_hex_color" => $drop[0]->boundary_hex_color,
                "drop_shape" => $drop[0]->boundary_type,
                "drop_radius" => $drop[0]->boundary_radius,
                "drop_bounds" => $drop[0]->boundary_bounds,
                "drop_latlngs" => $drop[0]->boundary_latlngs,
                "drop_points" => $drop[0]->boundary_points,
                // 'pic_name' => $drop_pic[0]->pic_name,
                // 'pic_phone_code' => $drop_pic[0]->pic_phone_code,
                // 'pic_phone_val' => $drop_pic[0]->pic_phone,
                // 'pic_mail' => $drop_pic[0]->pic_mail,
                "pic_name" => $req->auth->first_name,
                "pic_phone_code" => $req->auth->phone_code,
                "pic_phone_val" => $req->auth->phone,
                "pic_mail" => $req->auth->email,
            ];
            $drop_id = OrdersDrops::add($insDrop);

            $insClient = [
                "ord_id" => $ord_id,
                "ord_code" => $code,
                "c_id" => $req->auth->uid,
                "c_name" => $req->auth->first_name,
                "c_phone_code" => $req->auth->phone_code,
                "c_phone_val" => $req->auth->phone,
                "c_mail" => $req->auth->email,
                "c_addr" => $req->auth->fulladdress,
                "c_disc_type" => $client[0]->disc_type,
                "c_disc_amount" => $client[0]->disc_amount,
                "c_pt_id" => $client[0]->id,
                "c_pt_div_id" => $req->auth->client_div_id,
                "c_pt_gp_id" => $req->auth->client_gp_id,
                "c_pt_name" => $client[0]->c_name,
                "c_pt_phone_code" => $client[0]->c_phone_code,
                "c_pt_phone_val" => $client[0]->c_phone,
                "c_pt_mail" => $client[0]->c_mail,
                "c_pt_addr" => $client[0]->c_addr_office,
                "c_pt_pic_name" => $client[0]->pic_name,
                "c_pt_pic_phone_code" => $client[0]->pic_phone_code,
                "c_pt_pic_phone_val" => $client[0]->pic_phone,
                "c_pt_pic_mail" => $client[0]->pic_mail,
                "c_pt_pic_addr" => null,
                "prefer_truck_type" => 1,
            ];
            $ord_client_id = OrdersClients::add($insClient);

            if (count($insurance) > 0) {
                $insInsurance = [
                    "ord_id" => $ord_id,
                    "ord_code" => $code,
                    "insurance_id" => $insurance[0]->id,
                    "premi_name" => $insurance[0]->premi_name,
                    "premi_price" => $insurance[0]->premi_price,
                    "premi_min_price" => $insurance[0]->premi_min_price,
                    "premi_max_price" => $insurance[0]->premi_max_price,
                    "desc" => $insurance[0]->desc,
                ];
                OrdersInsurances::add($insInsurance);
            }
            Orders::updateOrder($ord_id, [
                "status" => Orders::STTS_HAVE_GET_VHC,
            ]);
            Vehicles::updateVehicle($req->vehicle_id, [
                "is_in_ord" => Vehicles::IN_ORD_YES,
                "ord_id" => $ord_id,
                "ord_code" => $code,
                "c_did" => $req->driver_id,
                "a_did" => $req->driver_id,
            ]);
            Drivers::updateDriver($req->driver_id, [
                "is_in_ord" => Drivers::IN_ORD_YES,
                "ord_id" => $ord_id,
                "ord_code" => $code,
            ]);
            $order = Orders::showOrder([
                "id" => $ord_id,
                "get_exp_vendor" => 1,
                // "vdr_id" => $req->auth->uid,
            ]);
            $driver = Drivers::getDriverByIdAllData($req->driver_id);
            $vehicle = Vehicles::getVehicleByIdAllData($req->vehicle_id);
            OrdersDrivers::add([
                "ord_id" => $order[0]->ord_id,
                "ord_code" => $order[0]->ord_code,
                "vdr_id" => $driver[0]->vendor_id,
                "drv_id" => $driver[0]->drv_id,
                "drv_name" => $driver[0]->fullname,
                "drv_mail" => $driver[0]->email,
                "drv_name2" => $driver[0]->fullname2,
                "drv_phone_code" => $driver[0]->phone_code,
                "drv_phone_val" => $driver[0]->phone,
                "drv_phone2_code" => $driver[0]->phone2_code,
                "drv_phone2_val" => $driver[0]->phone2,
                "drv_addr" => $driver[0]->fulladdress,
                "drv_cgroup_id" => $driver[0]->client_group_id,
                "drv_nik" => $driver[0]->nik,
                "drv_dob" => $driver[0]->dob,
                "drv_age" => Helper::countAge($driver[0]->dob),
                "drv_gender" => $driver[0]->gender,
                "drv_blood" => $driver[0]->blood,
                "em_fullname" => $driver[0]->em_fullname,
                "em_phone_code" => $driver[0]->em_phone_code,
                "em_phone_val" => $driver[0]->em_phone,
                "em_relationship" => $driver[0]->em_relationship,
                "drv_ktp_img" => $driver[0]->ktp_img,
                "drv_npwp_img" => $driver[0]->npwp_img,
                "drv_npwp_number" => $driver[0]->npwp_number,
                "drv_npwp_string" => $driver[0]->npwp_string,
                "drv_license_img" => $driver[0]->license_img,
                "drv_license_number" => $driver[0]->license_number,
                "drv_license_exp" => $driver[0]->license_exp,
            ]);
            OrdersVehicles::add([
                "ord_id" => $order[0]->ord_id,
                "ord_code" => $order[0]->ord_code,
                "vhc_id" => $vehicle[0]->vhc_id,
                "vhc_name" => $vehicle[0]->name,
                "vhc_device_id" => $vehicle[0]->device_id,
                "vhc_cat_id" => $vehicle[0]->cat_id,
                "vhc_brand_id" => $vehicle[0]->brand_id,
                "vhc_type_id" => $vehicle[0]->type_id,
                "vhc_model_id" => $vehicle[0]->model_id,
                "vhc_c_did" => $vehicle[0]->c_did,
                "vhc_a_did" => $vehicle[0]->a_did,
                "vhc_nopol1" => $vehicle[0]->nopol1,
                "vhc_nopol2" => $vehicle[0]->nopol2,
                "vhc_nopol3" => $vehicle[0]->nopol3,
                "vhc_is_track_holiday" => $vehicle[0]->is_track_holiday,
                "vhc_track_sch_d" => $vehicle[0]->track_sch_d,
                "vhc_track_sch_h" => $vehicle[0]->track_sch_h,
                "vhc_cgroup_id" => $vehicle[0]->client_group_id,
                "vhc_vdr_id" => $vehicle[0]->vendor_id,
                "vhc_speed_limit" => $vehicle[0]->speed_limit,
                "vhc_fuel_capacity" => $vehicle[0]->fuel_capacity,
                "vhc_fuel_drop_treshold" => $vehicle[0]->fuel_drop_treshold,
                "vhc_max_pressure" => $vehicle[0]->max_pressure,
                "vhc_fvhc_img" => $vehicle[0]->fvhc_img,
                "vhc_stnk_img" => $vehicle[0]->stnk_img,
                "vhc_stnk_exp" => $vehicle[0]->stnk_exp,
                "vhc_vyear" => $vehicle[0]->vyear,
                "vhc_cc" => $vehicle[0]->cc,
                "vhc_vin" => $vehicle[0]->vin,
                "vhc_en" => $vehicle[0]->en,
                "vhc_vcolor" => $vehicle[0]->vcolor,
                "vhc_fuel_type" => $vehicle[0]->fuel_type,
                "vhc_tnkb_color" => $vehicle[0]->tnkb_color,
                "vhc_regis_year" => $vehicle[0]->regis_year,
                "vhc_tax_exp" => $vehicle[0]->tax_exp,
            ]);

            $dt_inst_pck_drop = [
                "ord_id" => $order[0]->ord_id,
                "ord_code" => $order[0]->ord_code,
                "pck_id" => $pck_id,
                "drop_id" => $drop_id,
                "is_active" => 1,
                "stts" => 1,
            ];
            DB::table("t_orders_pck_drop")->insert($dt_inst_pck_drop);

            $apiResp = Responses::created("success create order");

            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_list_orders(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->auth->role == Users::ROLE_ADMIN) {
            } elseif ($req->auth->role == Users::ROLE_CLIENT_ADMIN) {
                $filter["client_id"] = $req->auth->uid;
            } elseif ($req->auth->role == Users::ROLE_VENDOR) {
                $filter["vendor_id"] = $req->auth->uid;
            } elseif ($req->auth->role == Users::ROLE_CHECKER) {
                $filter["get_stts_checker"] = 1;
                $filter["chk_id"] = $req->auth->uid;
                $filter["chk_type"] = $req->auth->chk_type;
                $filter["ready_checker"] = 1;
            } else {
                $filter["client_id"] = 0;
            }

            if ($req->cptid) {
                $filter["client_pt_id"] = $req->cptid;
            }
            if ($req->couple_pck_drop) {
                $filter["couple_pck_drop"] = 1;
            }
            if ($req->order_by === "desc") {
                $filter["order_by"] = "ord.id DESC";
            }

            $list = Orders::listOrders($filter);
            $newList = [];
            $cntK = 0;
            foreach ($list as $key => $row) {
                $list[$key]->action = "-";
                if ($req->auth->role == Users::ROLE_CHECKER) {
                } else {
                    $isSame = 0;
                    foreach ($newList as $nlK => $rowL) {
                        if (!$row->group_code) {
                            continue;
                        }
                        if ($row->group_code === $rowL->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 orders");
            $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_show_order(Request $req, $ord_id)
    {
        try {
            $now = time();

            $input = [
                "ord_id" => $ord_id,
                "get_current_track_vhcs" => $req->get_current_track_vhcs,
                "couple_pck_drop" => $req->couple_pck_drop,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "get_current_track_vhcs" => "nullable|numeric",
                "couple_pck_drop" => "nullable|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"]);
            }

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

            $apiResp = Responses::success("success detail order");
            $apiResp["data"] = $order[0];

            if ($req->get_current_track_vhcs) {
                // $rate = ConfRates::getRateById($order[0]->rate_id);
                $rate = OrdersRates::getById($order[0]->ord_rate_id);
                $filter = [
                    "status" => Vehicles::STTS_ACTIVE,
                    "is_in_ord" => Vehicles::IN_ORD_NO,
                    "active_rates" => $rate[0],
                ];
                if ($order[0]->prefer_truck_type != 0) {
                    $filter["prefer_truck_type"] = $order[0]->prefer_truck_type;
                }
                $list_current_track_vhcs = Tracks::listCurrentTracks($filter);
                $apiResp["list_current_track_vhcs"] = $list_current_track_vhcs;
            }

            if ($req->drv_ups) {
                $apiResp["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,
                ]);
            }

            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_download_package_list(Request $req, $ord_id)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $ord_id,
            ];
            $rulesInput = [
                "ord_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 = [];
            // if ($req->auth->role != Users::ROLE_CHECKER) {
            $filter["get_not_deleted"] = 1;
            // }

            $items = OrdersItems::getsByOrdId($ord_id, $filter);
            if (count($items) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $apiResp = Responses::success("success get package list");
            $apiResp["data"] = $items;
            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_adm_find_driver(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
                "boundary_type" => $req->boundary_type,
                "boundary_latlngs" => $req->boundary_latlngs,
                "boundary_bounds" => $req->boundary_bounds,
                "boundary_radius" => $req->boundary_radius,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "boundary_type" => "required|string|max:25",
                "boundary_latlngs" => "required|array",
                "boundary_latlngs.*.lat" => "required",
                "boundary_latlngs.*.lng" => "required",
                "boundary_bounds" => "nullable|array",
                "boundary_radius" => "nullable|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"]);
            }

            $filter = [
                "id" => $req->ord_id,
                "get_prefer_type_truck" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $apiResp = Responses::success("success get order");
            $apiResp["data"] = $order[0];

            // $rate = ConfRates::getRateById($order[0]->rate_id);
            $rate = OrdersRates::getById($order[0]->ord_rate_id);
            $filter = [
                "active_rates" => $rate[0],
            ];
            if ($order[0]->prefer_truck_type != 0) {
                $filter["prefer_truck_type"] = $order[0]->prefer_truck_type;
            }

            $lat = $req->boundary_latlngs[0]["lat"];
            $lng = $req->boundary_latlngs[0]["lng"];
            $nearest = Tracks::nearestInCircle($lat, $lng, $req->boundary_radius, $filter);
            if (count($nearest) < 1) {
                $apiResp = Responses::not_found("no vehicle available");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $found_prefer = 0;
            $group_vendors = [];
            foreach ($nearest as $k => $v) {
                $is_add_vendor = 1;
                if ($order[0]->prefer_truck_type !== 0) {
                    if ($v->type_id === $order[0]->prefer_truck_type) {
                        $found_prefer = 1;
                    } else {
                        // remove from array but no reindex array
                        // unset($nearest[$k]);
                        // remove from array and reindex array
                        array_splice($nearest, $k, 1);
                        $is_add_vendor = 0;
                    }
                }
                if ($is_add_vendor) {
                    if (!isset($group_vendors[(int) $v->vendor_id])) {
                        // $token = Str::uuid()->toString();
                        $token = (new Nanoid())->generateId(36);
                        $group_vendors[(int) $v->vendor_id] = [
                            "vendor_id" => $v->vendor_id,
                            "vendor_name" => $v->vendor_name,
                            "vendor_phone" =>
                                $v->vendor_phone . " " . implode(" ", str_split($v->vendor_phone, 4)),
                            "vendor_phone_code" => $v->vendor_phone_code,
                            "vendor_phone_val" => $v->vendor_phone,
                            "vendor_mail" => $v->vendor_mail,
                            "vendor_addr" => $v->vendor_addr,
                            "vendor_bank_id" => $v->bank_id,
                            "vendor_bank_code" => $v->bank_code,
                            "vendor_bank_short_name" => $v->bank_short_name,
                            "vendor_bank_name" => $v->bank_name,
                            "vendor_bank_acc_number" => $v->bank_acc_number,
                            "vendor_bank_acc_name" => $v->bank_acc_name,
                            "vendor_acc_link" =>
                                route("view_user_vendor_transaction_bid_order") . "?token=" . $token,
                            "vhcs" => $v->id . ",", // string vhc_ids per vendor separated by comma
                            "token" => $token,
                            "distance" => $v->distance,
                        ];
                    } else {
                        $group_vendors[(int) $v->vendor_id]["vhcs"] .= $v->id . ",";
                    }
                }
            }
            $apiResp["nearest"] = $nearest;

            if ($order[0]->prefer_truck_type != 0) {
                if ($found_prefer === 0) {
                    // $tt = ConfTruckTypes::getTypeById($order[0]->prefer_truck_type);
                    $apiResp = Responses::not_found(
                        "no vehicle available with prefered type truck " . $order[0]->prefer_truck_type_name
                    );
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            // return (new Response($apiResp, 400));

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "confirm_at" => $now,
                "confirm_by" => $req->auth->id,
                "find_vhc_at" => $now,
                "find_vhc_by" => $req->auth->id,
                "status" => Orders::STTS_CONFIRM,
                "updt" => $now,
                "updt_by" => $req->auth->id,
            ]);

            $vendors = [];
            $ik = 0;
            foreach ($group_vendors as $k => $v) {
                $checkIsIns = OrdersVendors::getByOrdIdAndVdrId($order[0]->ord_id, $v["vendor_id"]);
                if (count($checkIsIns) > 0) {
                    continue;
                }
                $vendor = [
                    "vendor_id" => $v["vendor_id"],
                    "vendor_name" => $v["vendor_name"],
                    "vendor_phone" => $v["vendor_phone"],
                    "vendor_mail" => $v["vendor_mail"],
                    "vendor_addr" => $v["vendor_addr"],
                    "vendor_acc_link" => $v["vendor_acc_link"],
                ];
                array_push($vendors, $vendor);

                if (strpos($v["vhcs"], ",") !== false) {
                    $v["vhcs"] = substr($v["vhcs"], 0, -1);
                }

                // $is_mailing_bid = OrdersVendors::IS_MAILING_BID_NOT;
                // $is_mailing_bid_at = 0;
                // $exp_at = 0;
                // $is_exp = OrdersVendors::LINK_NOT_EXP;
                // if ($ik === 0) {
                $is_mailing_bid = OrdersVendors::IS_MAILING_BID_SEND;
                $is_mailing_bid_at = $now;
                $exp_at = strtotime("+10 minutes", $now);
                // $exp_at = strtotime('+1 day', $now);
                $is_exp = OrdersVendors::LINK_WILL_EXP;
                // }

                $insVendors = [
                    "ord_id" => $order[0]->ord_id,
                    "ord_code" => $order[0]->ord_code,
                    "vdr_id" => $v["vendor_id"],
                    "vdr_name" => $v["vendor_name"],
                    "vdr_mail" => $v["vendor_mail"],
                    "vdr_phone_code" => $v["vendor_phone_code"],
                    "vdr_phone_val" => $v["vendor_phone_val"],
                    "vdr_addr" => $v["vendor_addr"],
                    "vdr_bank_id" => $v["vendor_bank_id"],
                    "vdr_bank_code" => $v["vendor_bank_code"],
                    "vdr_bank_short_name" => $v["vendor_bank_short_name"],
                    "vdr_bank_name" => $v["vendor_bank_name"],
                    "vdr_bank_acc_number" => $v["vendor_bank_acc_number"],
                    "vdr_bank_acc_name" => $v["vendor_bank_acc_name"],
                    "find_vhcs" => $v["vhcs"],
                    "find_radius" => $req->boundary_radius,
                    "find_shape" => Zone::ZONE_BOUNDARY_CIRCLE,
                    "find_center_lat" => $req->boundary_latlngs[0]["lat"],
                    "find_center_lng" => $req->boundary_latlngs[0]["lng"],
                    "distance" => $v["distance"],
                    "is_exp" => $is_exp,
                    "exp_at" => $exp_at,
                    "bid_token" => $v["token"],
                    "is_mailing_bid" => $is_mailing_bid,
                    "is_mailing_bid_at" => $is_mailing_bid_at,
                    "status" => OrdersVendors::STTS_WAIT,
                    "crt" => $now,
                ];
                OrdersVendors::add($insVendors);
                $ik++;
            }

            if (count($vendors) > 0) {
                // run schedule 3x dalam 10 menit
                $url = env("API_URL_NODE") . "/order/delay_blast_order";
                $guzReq = new GuzzleClient();
                $respNode = $guzReq->request("POST", $url, [
                    "headers" => [
                        "Host" => $_SERVER["SERVER_ADDR"],
                        "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" => [
                        "ord_id" => $order[0]->ord_id,
                        "ord_code" => $order[0]->ord_code,
                        "base_link" => route("view_user_vendor_transaction_bid_order") . "?token=",
                    ],
                ]);
                if ($respNode->getStatusCode() != 200) {
                    DB::rollBack();
                    $apiResp = Responses::bad_request("fail setup scheduler on 10 minutes later");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                // $body = json_decode($respNode->getBody()->getContents());

                $url = env("API_URL_NODE") . "/order/email_to_vendor";
                $guzReq = new GuzzleClient();
                $respNode = $guzReq->request("POST", $url, [
                    "headers" => [
                        "Host" => $_SERVER["SERVER_ADDR"],
                        "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,
                        "trx_at" => $order[0]->crt,
                        "client_id" => $order[0]->c_id,
                        "client_name" => $order[0]->c_name,
                        "client_phone" =>
                            $order[0]->c_phone_code .
                            " " .
                            implode(" ", str_split($order[0]->c_phone_val, 4)),
                        "client_mail" => $order[0]->c_mail,
                        "client_addr" => "",
                        "client_prefer_type_truck" => $order[0]->prefer_truck_type_name ?? "",
                        // "weight" => $order[0]->weight,
                        // "cbm" => $order[0]->cbm,
                        // "koli" => $order[0]->koli,
                        "pickup_zone_title" => $order[0]->pck_name,
                        "pickup_zone_addr" => $order[0]->pck_addr,
                        "pickup_at" => $order[0]->set_pck_at,
                        "drop_zone_title" => $order[0]->drop_name,
                        "drop_zone_addr" => $order[0]->drop_addr,
                        "vendors" => $vendors,
                    ],
                ]);
                if ($respNode->getStatusCode() != 200) {
                    DB::rollBack();
                    $apiResp = Responses::bad_request("fail send email to vendor");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                // $body = json_decode($respNode->getBody()->getContents());
            }

            DB::commit();
            $apiResp = Responses::success("success confirm order");
            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_adm_assign_vendor(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
                "vendor_id" => $req->vendor_id,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "vendor_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_id,
                "get_prefer_type_truck" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $apiResp = Responses::success("success get order");
            $apiResp["data"] = $order[0];

            $vendor = Users::getUserById($req->vendor_id);
            if (count($vendor) < 1) {
                $apiResp = Responses::not_found("vendor not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $found_prefer = 0;
            $group_vendors = [];

            // $token = Str::uuid()->toString();
            $token = (new Nanoid())->generateId(36);
            $group_vendors[(int) $vendor[0]->id] = [
                "vendor_id" => $vendor[0]->id,
                "vendor_name" => $vendor[0]->first_name,
                "vendor_phone" => $vendor[0]->phone . " " . implode(" ", str_split($vendor[0]->phone, 4)),
                "vendor_phone_code" => $vendor[0]->phone_code,
                "vendor_phone_val" => $vendor[0]->phone,
                "vendor_mail" => $vendor[0]->email,
                "vendor_addr" => $vendor[0]->fulladdress,
                "vendor_bank_id" => $vendor[0]->bank_id,
                "vendor_bank_code" => $vendor[0]->bank_code,
                "vendor_bank_short_name" => $vendor[0]->bank_short_name,
                "vendor_bank_name" => $vendor[0]->bank_name,
                "vendor_bank_acc_number" => $vendor[0]->bank_acc_number,
                "vendor_bank_acc_name" => $vendor[0]->bank_acc_name,
                "vendor_acc_link" => route("view_user_vendor_transaction_bid_order") . "?token=" . $token,
                "vhcs" => "", // string vhc_ids per vendor separated by comma
                "token" => $token,
            ];

            $vhcs = Vehicles::getVehiclesInVendorIdsActiveNoInOrder(
                "" . $vendor[0]->id,
                $order[0]->prefer_truck_type
            );
            foreach ($vhcs as $vhc) {
                if ($vhc->type_id === $order[0]->prefer_truck_type) {
                    $found_prefer = 1;
                }
                $group_vendors[(int) $vendor[0]->id]["vhcs"] .= $vhc->id . ",";
            }

            if ($order[0]->prefer_truck_type != 0) {
                if ($found_prefer === 0) {
                    // $tt = ConfTruckTypes::getTypeById($order[0]->prefer_truck_type);
                    $apiResp = Responses::not_found(
                        "no vehicle available with prefered type truck " . $order[0]->prefer_truck_type_name
                    );
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            // return (new Response($apiResp, 400));

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "confirm_at" => $now,
                "confirm_by" => $req->auth->id,
                "find_vhc_at" => $now,
                "find_vhc_by" => $req->auth->id,
                "status" => Orders::STTS_CONFIRM,
                "updt" => $now,
                "updt_by" => $req->auth->id,
            ]);

            $vendors = [];
            $ik = 0;
            foreach ($group_vendors as $k => $v) {
                $checkIsIns = OrdersVendors::getByOrdIdAndVdrId($order[0]->ord_id, $v["vendor_id"]);
                if (count($checkIsIns) > 0) {
                    continue;
                }
                $vendor = [
                    "vendor_id" => $v["vendor_id"],
                    "vendor_name" => $v["vendor_name"],
                    "vendor_phone" => $v["vendor_phone"],
                    "vendor_mail" => $v["vendor_mail"],
                    "vendor_addr" => $v["vendor_addr"],
                    "vendor_acc_link" => $v["vendor_acc_link"],
                ];
                array_push($vendors, $vendor);

                if (strpos($v["vhcs"], ",") !== false) {
                    $v["vhcs"] = substr($v["vhcs"], 0, -1);
                }

                // $is_mailing_bid = OrdersVendors::IS_MAILING_BID_NOT;
                // $is_mailing_bid_at = 0;
                // $exp_at = 0;
                // $is_exp = OrdersVendors::LINK_NOT_EXP;
                // if ($ik === 0) {
                $is_mailing_bid = OrdersVendors::IS_MAILING_BID_SEND;
                $is_mailing_bid_at = $now;
                $exp_at = strtotime("+10 minutes", $now);
                // $exp_at = strtotime('+1 day', $now);
                $is_exp = OrdersVendors::LINK_WILL_EXP;
                // }

                $insVendors = [
                    "ord_id" => $order[0]->ord_id,
                    "ord_code" => $order[0]->ord_code,
                    "vdr_id" => $v["vendor_id"],
                    "vdr_name" => $v["vendor_name"],
                    "vdr_mail" => $v["vendor_mail"],
                    "vdr_phone_code" => $v["vendor_phone_code"],
                    "vdr_phone_val" => $v["vendor_phone_val"],
                    "vdr_addr" => $v["vendor_addr"],
                    "vdr_bank_id" => $v["vendor_bank_id"],
                    "vdr_bank_code" => $v["vendor_bank_code"],
                    "vdr_bank_short_name" => $v["vendor_bank_short_name"],
                    "vdr_bank_name" => $v["vendor_bank_name"],
                    "vdr_bank_acc_number" => $v["vendor_bank_acc_number"],
                    "vdr_bank_acc_name" => $v["vendor_bank_acc_name"],
                    "find_vhcs" => $v["vhcs"],
                    "is_exp" => $is_exp,
                    "exp_at" => $exp_at,
                    "bid_token" => $v["token"],
                    "is_mailing_bid" => $is_mailing_bid,
                    "is_mailing_bid_at" => $is_mailing_bid_at,
                    "status" => OrdersVendors::STTS_WAIT,
                    "crt" => $now,
                ];
                OrdersVendors::add($insVendors);
                $ik++;
            }
            // if (count($vendors) > 0) {
            //     // run schedule 3x dalam 10 menit
            //     $url = env("API_URL_NODE") . "/order/delay_blast_order";
            //     $guzReq = new GuzzleClient();
            //     $respNode = $guzReq->request("POST", $url, [
            //         "headers" => [
            //             "Host" => $_SERVER["SERVER_ADDR"],
            //             "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" => [
            //             "ord_id" => $order[0]->ord_id,
            //             "ord_code" => $order[0]->ord_code,
            //             "base_link" =>
            //                 route("view_user_vendor_transaction_bid_order") .
            //                 "?token=",
            //         ],
            //     ]);
            //     if ($respNode->getStatusCode() != 200) {
            //         DB::rollBack();
            //         $apiResp = Responses::bad_request(
            //             "fail setup schedule 3x10 minutes"
            //         );
            //         return new Response($apiResp, $apiResp["meta"]["code"]);
            //     }
            //     // $body = json_decode($respNode->getBody()->getContents());

            //     $url = env("API_URL_NODE") . "/order/email_to_vendor";
            //     $guzReq = new GuzzleClient();
            //     $respNode = $guzReq->request("POST", $url, [
            //         "headers" => [
            //             "Host" => $_SERVER["SERVER_ADDR"],
            //             "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,
            //             "trx_at" => $order[0]->crt,
            //             "client_id" => $order[0]->c_id,
            //             "client_name" => $order[0]->c_name,
            //             "client_phone" =>
            //                 $order[0]->c_phone_code .
            //                 " " .
            //                 implode(" ", str_split($order[0]->c_phone_val, 4)),
            //             "client_mail" => $order[0]->c_mail,
            //             "client_addr" => "",
            //             "client_prefer_type_truck" =>
            //                 $order[0]->prefer_truck_type_name ?? "",
            //             // "weight" => $order[0]->weight,
            //             // "cbm" => $order[0]->cbm,
            //             // "koli" => $order[0]->koli,
            //             "pickup_zone_title" => $order[0]->pck_name,
            //             "pickup_zone_addr" => $order[0]->pck_addr,
            //             "pickup_at" => $order[0]->set_pck_at,
            //             "drop_zone_title" => $order[0]->drop_name,
            //             "drop_zone_addr" => $order[0]->drop_addr,
            //             "vendors" => $vendors,
            //         ],
            //     ]);
            //     if ($respNode->getStatusCode() != 200) {
            //         DB::rollBack();
            //         $apiResp = Responses::bad_request(
            //             "fail send email to vendor"
            //         );
            //         return new Response($apiResp, $apiResp["meta"]["code"]);
            //     }
            //     // $body = json_decode($respNode->getBody()->getContents());
            // }

            DB::commit();
            $apiResp = Responses::success("success confirm order");
            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_want_this_order_v1(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
            ];
            $rulesInput = [
                "ord_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"]);
            }

            $order = Orders::showOrder([
                "id" => $req->ord_id,
                "get_exp_vendor" => 1,
                "vdr_id" => $req->auth->uid,
            ]);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            // if ($order[0]->vdr_is_exp === OrdersVendors::LINK_WILL_EXP) {
            //     if ($order[0]->vdr_exp_at < time()) {
            //         $apiResp = Responses::bad_request("link expired");
            //         return new Response($apiResp, $apiResp["meta"]["code"]);
            //     }
            // }

            // validate if another vendor want this order
            $otherVendorsWantThisOrder = OrdersVendors::getOtherVendorsWantThisOrder(
                $order[0]->ord_id,
                $req->auth->uid
            );
            if (count($otherVendorsWantThisOrder) > 0) {
                $apiResp = Responses::bad_request(
                    "There other vendor want this order, if next 10 minutes the vendor not take the order, we will send email again to you"
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            // $sendToNode = [
            // 	"ord_id" => $order[0]->ord_id,
            // 	"ord_code" => $order[0]->ord_code,
            // 	"current_ord_vdr_id" => $order[0]->ord_vdr_id,
            // 	"next_ord_vdr_id" => [],
            // 	"next_vdr_bid_token" => [],
            // 	"next_vdr_acc_link" => [],
            // ];

            // $nextVendors = OrdersVendors::getNextVendors($order[0]->ord_id, $req->auth->uid);
            // foreach ($nextVendors as $k => $v) {
            // 	$sendToNode['next_ord_vdr_id'][] = ['id' => $v->id];
            // 	$sendToNode['next_vdr_bid_token'][] = ['tkn' => $v->bid_token];
            // 	$sendToNode['next_vdr_acc_link'][] = ['link' => route('view_user_vendor_transaction_bid_order') . '?token=' . $v->bid_token];
            // }

            DB::beginTransaction();

            OrdersVendors::updt($order[0]->ord_vdr_id, [
                "is_want" => OrdersVendors::IS_WANT_YES,
                "is_want_at" => $now,
                "is_exp" => OrdersVendors::LINK_WILL_EXP,
                // 'exp_at' => strtotime('+10 minutes', $now),
            ]);

            // gaperlu dihit karena sekarang sudah pakai konsep run schedule 3x dalam 10 menit
            // $url = env('API_URL_NODE') . '/order/delay_blast_order';
            // $guzReq = new GuzzleClient();
            // $respNode = $guzReq->request('POST', $url, [
            // 	'headers' => [
            // 		'Host' => $_SERVER['SERVER_ADDR'],
            // 		'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' => $sendToNode,
            // ]);
            // if ($respNode->getStatusCode() != 200) {
            // 	DB::rollBack();
            // 	$apiResp = Responses::bad_request('fail setup scheduler on 10 minutes later');
            // 	return (new Response($apiResp, $apiResp['meta']['code']));
            // }
            // $body = json_decode($respNode->getBody()->getContents());

            DB::commit();
            $apiResp = Responses::success("success want this order");
            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_accept_order_v1(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
                "vehicle" => $req->vehicle, // id
                "driver" => $req->driver, // id
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "vehicle" => "required|integer|not_in:0",
                "driver" => "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"]);
            }

            $order = Orders::showOrder([
                "id" => $req->ord_id,
                "get_exp_vendor" => 1,
                "vdr_id" => $req->auth->uid,
            ]);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($order[0]->vdr_status !== OrdersVendors::STTS_WAIT) {
                // $apiResp = Responses::bad_request('you had respond this order');
                $apiResp = Responses::bad_request("order has been cancel");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($order[0]->status === Orders::STTS_WAIT || $order[0]->status === Orders::STTS_CONFIRM) {
            } else {
                $apiResp = Responses::bad_request("this order have beend accepted by another vendor");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            // date('Y-m-d H:i:s', $order[0]->vdr_exp_at);
            // comment by meus
            // if ($order[0]->vdr_is_exp === OrdersVendors::LINK_WILL_EXP) {
            //     if ($order[0]->vdr_exp_at < time()) {
            //         $apiResp = Responses::bad_request("link expired");
            //         return new Response($apiResp, $apiResp["meta"]["code"]);
            //     }
            // }
            $haveBeenAcc = OrdersVendors::getByOrdIdByStatus($req->ord_id, OrdersVendors::STTS_ACC);
            if (count($haveBeenAcc) > 0) {
                $apiResp = Responses::bad_request("this order have beend accepted by another vendor");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $driver = Drivers::getDriverByIdAllData($req->driver);
            if (count($driver) < 1) {
                $apiResp = Responses::not_found("driver not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($driver[0]->is_in_ord === Drivers::IN_ORD_YES) {
                $apiResp = Responses::not_found("driver telah ditugaskan untuk order lain");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $vehicle = Vehicles::getVehicleByIdAllData($req->vehicle);
            if (count($vehicle) < 1) {
                $apiResp = Responses::not_found("vehicle not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($vehicle[0]->is_in_ord === Vehicles::IN_ORD_YES) {
                $apiResp = Responses::not_found("vehicle telah ditugaskan untuk order lain");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            // $apiResp = Responses::success('success accept order');
            // return (new Response($apiResp, $apiResp['meta']['code']));

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "status" => Orders::STTS_HAVE_GET_VHC,
            ]);
            Vehicles::updateVehicle($req->vehicle, [
                "is_in_ord" => Vehicles::IN_ORD_YES,
                "ord_id" => $order[0]->ord_id,
                "ord_code" => $order[0]->ord_code,
            ]);
            Drivers::updateDriver($order[0]->drv_id, [
                "is_in_ord" => Drivers::IN_ORD_YES,
                "ord_id" => $order[0]->ord_id,
                "ord_code" => $order[0]->ord_code,
            ]);
            OrdersVendors::updt($order[0]->ord_vdr_id, [
                "respond_at" => $now,
                "status" => OrdersVendors::STTS_ACC,
            ]);
            OrdersDrivers::add([
                "ord_id" => $order[0]->ord_id,
                "ord_code" => $order[0]->ord_code,
                "vdr_id" => $driver[0]->vendor_id,
                "drv_id" => $driver[0]->drv_id,
                "drv_name" => $driver[0]->fullname,
                "drv_mail" => $driver[0]->email,
                "drv_name2" => $driver[0]->fullname2,
                "drv_phone_code" => $driver[0]->phone_code,
                "drv_phone_val" => $driver[0]->phone,
                "drv_phone2_code" => $driver[0]->phone2_code,
                "drv_phone2_val" => $driver[0]->phone2,
                "drv_addr" => $driver[0]->fulladdress,
                "drv_cgroup_id" => $driver[0]->client_group_id,
                "drv_nik" => $driver[0]->nik,
                "drv_dob" => $driver[0]->dob,
                "drv_age" => Helper::countAge($driver[0]->dob),
                "drv_gender" => $driver[0]->gender,
                "drv_blood" => $driver[0]->blood,
                "em_fullname" => $driver[0]->em_fullname,
                "em_phone_code" => $driver[0]->em_phone_code,
                "em_phone_val" => $driver[0]->em_phone,
                "em_relationship" => $driver[0]->em_relationship,
                "drv_ktp_img" => $driver[0]->ktp_img,
                "drv_npwp_img" => $driver[0]->npwp_img,
                "drv_npwp_number" => $driver[0]->npwp_number,
                "drv_npwp_string" => $driver[0]->npwp_string,
                "drv_license_img" => $driver[0]->license_img,
                "drv_license_number" => $driver[0]->license_number,
                "drv_license_exp" => $driver[0]->license_exp,
            ]);
            OrdersVehicles::add([
                "ord_id" => $order[0]->ord_id,
                "ord_code" => $order[0]->ord_code,
                "vhc_id" => $vehicle[0]->vhc_id,
                "vhc_name" => $vehicle[0]->name,
                "vhc_device_id" => $vehicle[0]->device_id,
                "vhc_cat_id" => $vehicle[0]->cat_id,
                "vhc_brand_id" => $vehicle[0]->brand_id,
                "vhc_type_id" => $vehicle[0]->type_id,
                "vhc_model_id" => $vehicle[0]->model_id,
                "vhc_c_did" => $vehicle[0]->c_did,
                "vhc_a_did" => $vehicle[0]->a_did,
                "vhc_nopol1" => $vehicle[0]->nopol1,
                "vhc_nopol2" => $vehicle[0]->nopol2,
                "vhc_nopol3" => $vehicle[0]->nopol3,
                "vhc_is_track_holiday" => $vehicle[0]->is_track_holiday,
                "vhc_track_sch_d" => $vehicle[0]->track_sch_d,
                "vhc_track_sch_h" => $vehicle[0]->track_sch_h,
                "vhc_cgroup_id" => $vehicle[0]->client_group_id,
                "vhc_vdr_id" => $vehicle[0]->vendor_id,
                "vhc_speed_limit" => $vehicle[0]->speed_limit,
                "vhc_fuel_capacity" => $vehicle[0]->fuel_capacity,
                "vhc_fuel_drop_treshold" => $vehicle[0]->fuel_drop_treshold,
                "vhc_max_pressure" => $vehicle[0]->max_pressure,
                "vhc_fvhc_img" => $vehicle[0]->fvhc_img,
                "vhc_stnk_img" => $vehicle[0]->stnk_img,
                "vhc_stnk_exp" => $vehicle[0]->stnk_exp,
                "vhc_vyear" => $vehicle[0]->vyear,
                "vhc_cc" => $vehicle[0]->cc,
                "vhc_vin" => $vehicle[0]->vin,
                "vhc_en" => $vehicle[0]->en,
                "vhc_vcolor" => $vehicle[0]->vcolor,
                "vhc_fuel_type" => $vehicle[0]->fuel_type,
                "vhc_tnkb_color" => $vehicle[0]->tnkb_color,
                "vhc_regis_year" => $vehicle[0]->regis_year,
                "vhc_tax_exp" => $vehicle[0]->tax_exp,
            ]);
            // $url = env("API_URL_NODE") . "/order/email_vendor_acc_order";
            // $guzReq = new GuzzleClient();
            // $respNode = $guzReq->request("POST", $url, [
            //     "headers" => [
            //         "Host" => $_SERVER["SERVER_ADDR"],
            //         "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,
            //         "trx_at" => $order[0]->crt,
            //         "client_id" => $order[0]->c_id,
            //         "client_name" => $order[0]->c_name,
            //         "client_phone" =>
            //             $order[0]->c_phone_code .
            //             " " .
            //             implode(" ", str_split($order[0]->c_phone_val, 4)),
            //         "client_mail" => $order[0]->c_mail,
            //         "client_addr" => "",
            //         "client_prefer_type_truck" =>
            //             $order[0]->prefer_truck_type_name ?? "",
            //         "weight" => $order[0]->weight,
            //         "cbm" => $order[0]->cbm,
            //         "koli" => $order[0]->koli,
            //         "pickup_zone_title" => $order[0]->pck_name,
            //         "pickup_zone_addr" => $order[0]->pck_addr,
            //         "pickup_at" => $order[0]->set_pck_at,
            //         "drop_zone_title" => $order[0]->drop_name,
            //         "drop_zone_addr" => $order[0]->drop_addr,
            //         "vendors" => [
            //             [
            //                 "vendor_id" => $order[0]->vdr_id,
            //                 "vendor_name" => $order[0]->vdr_name,
            //                 "vendor_phone" =>
            //                     $order[0]->vdr_phone_code .
            //                     " " .
            //                     implode(
            //                         " ",
            //                         str_split($order[0]->vdr_phone_val, 4)
            //                     ),
            //                 "vendor_mail" => $order[0]->vdr_mail,
            //                 // "vendor_addr" => $order[0]->vdr_addr,
            //                 "vendor_acc_at" => $now,
            //             ],
            //         ],
            //         "drivers" => [
            //             [
            //                 "driver_id" => $driver[0]->id,
            //                 "driver_name" => $driver[0]->fullname,
            //                 "driver_phone" =>
            //                     $driver[0]->phone_code .
            //                     " " .
            //                     implode(" ", str_split($driver[0]->phone, 4)),
            //                 "driver_mail" => $driver[0]->email,
            //                 // "driver_addr" => $driver[0]->fulladdress,
            //             ],
            //         ],
            //     ],
            // ]);
            // if ($respNode->getStatusCode() != 200) {
            //     DB::rollBack();
            //     $apiResp = Responses::bad_request("fail send email to vendor");
            //     return new Response($apiResp, $apiResp["meta"]["code"]);
            // }
            // $body = json_decode($respNode->getBody()->getContents());

            DB::commit();
            $apiResp = Responses::success("success accept order");
            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_checker_submit_items(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
                "type_check" => $req->type_check,
                "weight" => $req->weight,
                "cbm" => $req->cbm,
                // 'qty_total' => $req->qty_total,
                "koli" => $req->koli,
                "general_base64" => $req->general_base64,
                "goods_base64" => $req->goods_base64,
                "items" => $req->items,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "type_check" => "required|integer|not_in:0",
                "weight" => "required|numeric",
                "cbm" => "required|numeric",
                // 'qty_total' => 'required|integer|not_in:0',
                "koli" => "required|integer|not_in:0",
                "items" => "required|array",
                "items.*.id" => "required|numeric",
                "items.*.item_code" => "required|string|max:255",
                "items.*.desc" => "required|string",
                // 'items.*.qty' => 'required|numeric',
                "items.*.weight" => "required|numeric", // kg
                "items.*.length" => "required|numeric", // m
                "items.*.wide" => "required|numeric", // m
                "items.*.height" => "required|numeric", // m
                "items.*.cbm" => "required|numeric", // m
            ];

            // 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 (count($req->items) < 1) {
                $apiResp = Responses::bad_input("at least 1 item left remaining");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $url_general = null;
            $url_goods = null;
            $calc_weight = $req->weight; // total
            $calc_cbm = $req->cbm; // total
            $calc_qty = $req->qty_total ?? 0; // total
            $calc_koli = $req->koli; // total

            $order = Orders::showOrder([
                "id" => $req->ord_id,
                "get_stts_checker" => 1,
                // 'chk_id' => $req->auth->uid,
            ]);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            if ($req->type_check == Users::CHK_TYPE_PICKUP) {
                // case jika vehicle harus sedang ditempat
                // if ($order[0]->status === Orders::STTS_HAVE_GET_VHC || $order[0]->status === Orders::STTS_PCK || $order[0]->status === Orders::STTS_GO) {
                // } else {
                // 	$apiResp = Responses::bad_input('vehicle not in pickup zone');
                // 	return (new Response($apiResp, $apiResp['meta']['code']));
                // }
                // case jika checker bisa submit kapan saja
                if ($order[0]->status === Orders::STTS_WAIT || $order[0]->status === Orders::STTS_CONFIRM) {
                    $apiResp = Responses::bad_input("vehicle not in pickup zone");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            } elseif ($req->type_check == Users::CHK_TYPE_DROP) {
                // case jika vehicle harus sedang ditempat
                // if ($order[0]->status === Orders::STTS_GO || $order[0]->status === Orders::STTS_ARV || $order[0]->status === Orders::STTS_DROP || $order[0]->status === Orders::STTS_CLIENT_PAY) {
                // } else {
                // 	$apiResp = Responses::bad_input('vehicle not in drop zone');
                // 	return (new Response($apiResp, $apiResp['meta']['code']));
                // }
                // case jika checker bisa submit kapan saja
                if (
                    $order[0]->status === Orders::STTS_WAIT ||
                    $order[0]->status === Orders::STTS_CONFIRM ||
                    $order[0]->status === Orders::STTS_PCK
                ) {
                    $apiResp = Responses::bad_input("vehicle not in drop zone");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            } else {
                $apiResp = Responses::bad_input("location type not valid");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if ($req->general_base64 != "") {
                if ($req->type_check == Users::CHK_TYPE_PICKUP) {
                    $url_general =
                        "orders/" .
                        $order[0]->ord_id .
                        "/pickups/" .
                        $order[0]->ord_pck_id .
                        "/checkers/" .
                        $req->auth->uid .
                        "/general_$now.jpeg";
                } elseif ($req->type_check == Users::CHK_TYPE_DROP) {
                    $url_general =
                        "orders/" .
                        $order[0]->ord_id .
                        "/drops/" .
                        $order[0]->ord_drop_id .
                        "/checkers/" .
                        $req->auth->uid .
                        "/general_$now.jpeg";
                }
                if (!Storage::disk("public")->put($url_general, base64_decode($req->general_base64))) {
                    $apiResp = Responses::bad_request("fail upload image delivery order");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            if ($req->goods_base64 != "") {
                if ($req->type_check == Users::CHK_TYPE_PICKUP) {
                    $url_goods =
                        "orders/" .
                        $order[0]->ord_id .
                        "/pickups/" .
                        $order[0]->ord_pck_id .
                        "/checkers/" .
                        $req->auth->uid .
                        "/goods_$now.jpeg";
                } elseif ($req->type_check == Users::CHK_TYPE_DROP) {
                    $url_goods =
                        "orders/" .
                        $order[0]->ord_id .
                        "/drops/" .
                        $order[0]->ord_drop_id .
                        "/checkers/" .
                        $req->auth->uid .
                        "/goods_$now.jpeg";
                }
                if (!Storage::disk("public")->put($url_goods, base64_decode($req->goods_base64))) {
                    Storage::disk("public")->delete($url_general);
                    $apiResp = Responses::bad_request("fail upload image delivery order");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }

            DB::beginTransaction();

            // update checker if id > 0 and new items if id == 0
            foreach ($req->items as $k => $v) {
                // update
                if ($v["id"] > 0) {
                    if ($req->type_check == Users::CHK_TYPE_PICKUP) {
                        OrdersItems::updt($v["id"], [
                            "chk_pck_id" => $req->auth->uid,
                            "chk_pck_at" => $now,
                        ]);
                    } elseif ($req->type_check == Users::CHK_TYPE_DROP) {
                        OrdersItems::updt($v["id"], [
                            "chk_drop_id" => $req->auth->uid,
                            "chk_drop_at" => $now,
                        ]);
                    }
                }
                // new data
                else {
                    $insNewItem = [
                        "ord_id" => $order[0]->ord_id,
                        "ord_code" => $order[0]->ord_code,
                        "pck_id" => $order[0]->ord_pck_id,
                        "drop_id" => $order[0]->ord_drop_id,
                        "item_code" => $v["item_code"],
                        "desc" => $v["desc"],
                        "unit_weight" => OrdersItems::DEFAULT_WEIGHT_UNIT,
                        "weight" => $v["weight"],
                        "unit_dimension" => OrdersItems::DEFAULT_DIMENSION_UNIT,
                        "qty" => $v["qty"] ?? 0,
                        "length" => $v["length"],
                        "wide" => $v["wide"],
                        "height" => $v["height"],
                        "volume" => $v["cbm"],
                        "crt" => $now,
                    ];
                    if ($req->type_check == Users::CHK_TYPE_PICKUP) {
                        $insNewItem["chk_pck_new"] = $now;
                    } elseif ($req->type_check == Users::CHK_TYPE_DROP) {
                        $insNewItem["chk_drop_new"] = $now;
                    }
                    OrdersItems::add($insNewItem);
                }
            }

            // only delete if id > 0
            if ($req->items_deleted && count($req->items_deleted) > 0) {
                foreach ($req->items_deleted as $k => $v) {
                    if ($v["id"] > 0) {
                        if ($req->type_check == Users::CHK_TYPE_PICKUP) {
                            OrdersItems::updt($v["id"], [
                                "chk_pck_id" => $req->auth->uid,
                                "chk_pck_at" => $now,
                                "chk_pck_dlt" => $now,
                            ]);
                        } elseif ($req->type_check == Users::CHK_TYPE_DROP) {
                            OrdersItems::updt($v["id"], [
                                "chk_drop_id" => $req->auth->uid,
                                "chk_drop_at" => $now,
                                "chk_drop_dlt" => $now,
                            ]);
                        }
                    }
                }
            }

            if ($req->type_check == Users::CHK_TYPE_PICKUP) {
                // case jika sudah drop namun checker pickup belum upload dan harus upload
                if ($order[0]->pck_chk_stts == OrdersPickups::CHK_STTS_SUBMIT) {
                    $updt_stts_order = $order[0]->status;
                } else {
                    $check_updt_stts = [Orders::STTS_HAVE_GET_VHC, Orders::STTS_PCK];
                    if (in_array($order[0]->status, $check_updt_stts)) {
                        $updt_stts_order = Orders::STTS_GO;
                    } else {
                        $updt_stts_order = $order[0]->status;
                    }
                }
                OrdersPickups::updt($order[0]->ord_pck_id, [
                    // pck_* => dicomment pas tracking udah jalan
                    "pck_at" => $order[0]->pck_at ? $order[0]->pck_at : $now, // leave_at
                    "pck_enter_at" => $order[0]->pck_enter_at ? $order[0]->pck_enter_at : $now,
                    "pck_leave_at" => $order[0]->pck_leave_at ? $order[0]->pck_leave_at : $now,
                    "stts_pck" => OrdersPickups::STTS_PICKED,
                    "chk_id" => $req->auth->uid,
                    "chk_at" => $now,
                    "chk_stts" => OrdersPickups::CHK_STTS_SUBMIT,
                    "chk_img" => $url_general,
                    "chk_goods_img" => $url_goods,
                    "chk_name" => $req->auth->first_name,
                    "chk_mail" => $req->auth->email,
                    "chk_addr" => $req->auth->fulladdress,
                    "chk_phone_code" => $req->auth->phone_code,
                    "chk_phone_val" => $req->auth->phone,
                    "weight" => $calc_weight,
                    "cbm" => $calc_cbm,
                    "qty" => $calc_qty,
                ]);
                OrdersDrops::updt($order[0]->ord_drop_id, [
                    "est_weight" => $calc_weight,
                    "est_cbm" => $calc_cbm,
                    "est_qty" => $calc_qty,
                ]);
            } elseif ($req->type_check == Users::CHK_TYPE_DROP) {
                $check_updt_stts = [
                    Orders::STTS_HAVE_GET_VHC,
                    Orders::STTS_PCK,
                    Orders::STTS_GO,
                    Orders::STTS_ARV,
                    Orders::STTS_DROP,
                ];
                if (in_array($order[0]->status, $check_updt_stts)) {
                    $updt_stts_order = Orders::STTS_CLIENT_PAY;
                } else {
                    $updt_stts_order = $order[0]->status;
                }
                OrdersDrops::updt($order[0]->ord_drop_id, [
                    // drop_* => dicomment pas tracking udah jalan
                    "drop_at" => $order[0]->drop_at ? $order[0]->drop_at : $now, // leave_at
                    "drop_enter_at" => $order[0]->drop_enter_at ? $order[0]->drop_enter_at : $now,
                    "drop_leave_at" => $order[0]->drop_leave_at ? $order[0]->drop_leave_at : $now,
                    "stts_drop" => OrdersDrops::STTS_DROPED,
                    "chk_id" => $req->auth->uid,
                    "chk_at" => $now,
                    "chk_stts" => OrdersDrops::CHK_STTS_SUBMIT,
                    "chk_img" => $url_general,
                    "chk_goods_img" => $url_goods,
                    "chk_name" => $req->auth->first_name,
                    "chk_mail" => $req->auth->email,
                    "chk_addr" => $req->auth->fulladdress,
                    "chk_phone_code" => $req->auth->phone_code,
                    "chk_phone_val" => $req->auth->phone,
                    "weight" => $calc_weight,
                    "cbm" => $calc_cbm,
                    "qty" => $calc_qty,
                ]);
                // Vehicles::updateVehicle($order[0]->vhc_id, [
                // 	'is_in_ord' => Vehicles::IN_ORD_NO,
                // 	'ord_id' => 0,
                // 	'ord_code' => 0,
                // ]);
            }

            Orders::updateOrder($order[0]->ord_id, [
                "status" => $updt_stts_order,
                "going_at" => $order[0]->going_at ? $order[0]->going_at : $now,
                "arrived_at" => $order[0]->arrived_at ? $order[0]->arrived_at : $now,
                "weight" => $calc_weight,
                "cbm" => $calc_cbm,
                "qty" => $calc_qty,
            ]);

            DB::commit();
            $apiResp = Responses::success("success submit checker data");
            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_checker_submit_pickup(Request $req)
    {
        $now = time();
        $url_seal_img = null;
        $url_drv_armd_img = null;
        $url_nopol_img = null;
        $url_docs_client_img = [];
        $url_install_seal_img = null;
        $url_goods_img = null;
        try {
            $input = [
                "ord_id" => $req->ord_id,
                "ord_pck_id" => $req->ord_pck_id,
                "seal_number" => $req->seal_number,
                "seal_img_base64" => $req->seal_img_base64,
                "drv_armd_img_base64" => $req->drv_armd_img_base64,
                "nopol_img_base64" => $req->nopol_img_base64,
                "docs_client_img_base64" => $req->docs_client_img_base64,
                "install_seal_img_base64" => $req->install_seal_img_base64,
                "goods_img_base64" => $req->goods_img_base64,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "ord_pck_id" => "nullable|integer|not_in:0",
                "seal_number" => "required|numeric",
                "seal_img_base64" => "required|string",
                "drv_armd_img_base64" => "required|string",
                "nopol_img_base64" => "required|string",
                "docs_client_img_base64" => "required|array",
                "install_seal_img_base64" => "nullable|string",
                "goods_img_base64" => "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 (count($req->docs_client_img_base64) < 1) {
                $apiResp = Responses::bad_input("silahkan upload dokumen kelengkapan dari client");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $order = Orders::showOrder([
                "id" => $req->ord_id,
                "get_stts_checker" => 1,
                // 'chk_id' => $req->auth->uid,
            ]);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if (
                $order[0]->status === Orders::STTS_HAVE_GET_VHC ||
                $order[0]->status === Orders::STTS_PCK ||
                $order[0]->status === Orders::STTS_GO
            ) {
            } else {
                $apiResp = Responses::bad_input("kendaraan belum berada di zona pickup");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if ($req->seal_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->seal_img_base64
                );
                $type = "jpeg";
                if (strpos($req->seal_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_seal_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/seal_img_$now.$type";
                if (!Storage::disk("public")->put($url_seal_img, base64_decode($clearBase64))) {
                    $apiResp = Responses::bad_request("gagal upload foto seal");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            if ($req->drv_armd_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->drv_armd_img_base64
                );
                $type = "jpeg";
                if (strpos($req->drv_armd_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_drv_armd_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/drv_armd_img_$now.$type";
                if (!Storage::disk("public")->put($url_drv_armd_img, base64_decode($clearBase64))) {
                    Storage::disk("public")->delete($url_seal_img);
                    $apiResp = Responses::bad_request("gagal upload foto driver armada");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            if ($req->nopol_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->nopol_img_base64
                );
                $type = "jpeg";
                if (strpos($req->nopol_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_nopol_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/nopol_img_$now.$type";
                if (!Storage::disk("public")->put($url_nopol_img, base64_decode($clearBase64))) {
                    Storage::disk("public")->delete($url_seal_img);
                    Storage::disk("public")->delete($url_drv_armd_img);
                    $apiResp = Responses::bad_request("fail upload foto nomor polisi");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            if ($req->docs_client_img_base64 && count($req->docs_client_img_base64) > 0) {
                $skip = false;
                foreach ($req->docs_client_img_base64 as $i => $img) {
                    if ($skip) {
                        continue;
                    }
                    $clearBase64 = preg_replace(
                        "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                        "",
                        $img
                    );
                    $type = "jpeg";
                    if (strpos($img, "application/pdf") !== false) {
                        $type = "pdf";
                    }
                    $url_docs_client_img[$i] =
                        "orders/" .
                        $order[0]->ord_id .
                        "/pickups/" .
                        $order[0]->ord_pck_id .
                        "/checkers/" .
                        $req->auth->uid .
                        "/docs_client_img_$now" .
                        "_" .
                        "$i.$type";
                    if (
                        !Storage::disk("public")->put($url_docs_client_img[$i], base64_decode($clearBase64))
                    ) {
                        Storage::disk("public")->delete($url_seal_img);
                        Storage::disk("public")->delete($url_drv_armd_img);
                        Storage::disk("public")->delete($url_nopol_img);
                        $apiResp = Responses::bad_request("gagal upload foto dokumen kelengkapan client");
                        return new Response($apiResp, $apiResp["meta"]["code"]);
                    }
                }
            }
            if ($req->install_seal_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->install_seal_img_base64
                );
                $type = "jpeg";
                if (strpos($req->install_seal_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_install_seal_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/install_seal_img_$now.$type";
                if (!Storage::disk("public")->put($url_install_seal_img, base64_decode($clearBase64))) {
                    Storage::disk("public")->delete($url_seal_img);
                    Storage::disk("public")->delete($url_drv_armd_img);
                    Storage::disk("public")->delete($url_nopol_img);
                    foreach ($url_docs_client_img as $path) {
                        Storage::disk("public")->delete($path);
                    }
                    $apiResp = Responses::bad_request("gagal upload foto pemasangan seal");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            if ($req->goods_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->goods_img_base64
                );
                $type = "jpeg";
                if (strpos($req->goods_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_goods_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/goods_img_$now.$type";
                if (!Storage::disk("public")->put($url_goods_img, base64_decode($clearBase64))) {
                    Storage::disk("public")->delete($url_seal_img);
                    Storage::disk("public")->delete($url_drv_armd_img);
                    Storage::disk("public")->delete($url_nopol_img);
                    foreach ($url_docs_client_img as $path) {
                        Storage::disk("public")->delete($path);
                    }
                    Storage::disk("public")->delete($url_install_seal_img);
                    $apiResp = Responses::bad_request("gagal upload foto barang");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "status" => Orders::STTS_GO,
                "going_at" => $order[0]->going_at ? $order[0]->going_at : $now,
                "chk_stts" => Orders::CHK_STTS_HAS_PICKUP,
            ]);

            OrdersPickups::updt($order[0]->ord_pck_id, [
                // pck_* => dicomment pas tracking udah jalan
                "pck_at" => $order[0]->pck_at ? $order[0]->pck_at : $now, // leave_at
                "pck_enter_at" => $order[0]->pck_enter_at ? $order[0]->pck_enter_at : $now,
                "pck_leave_at" => $order[0]->pck_leave_at ? $order[0]->pck_leave_at : $now,
                "stts_pck" => OrdersPickups::STTS_PICKED,
                "chk_id" => $req->auth->uid,
                "chk_at" => $now,
                "chk_stts" => OrdersPickups::CHK_STTS_SUBMIT,
                "chk_seal_number" => $req->seal_number,
                "chk_seal_img" => $url_seal_img,
                "chk_drv_armd_img" => $url_drv_armd_img,
                "chk_nopol_img" => $url_nopol_img,
                "chk_docs_client_img" => json_encode($url_docs_client_img),
                "chk_seal_install_img" => $url_install_seal_img,
                "chk_goods_img" => $url_goods_img,
                "chk_name" => $req->auth->first_name,
                "chk_mail" => $req->auth->email,
                "chk_addr" => $req->auth->fulladdress,
                "chk_phone_code" => $req->auth->phone_code,
                "chk_phone_val" => $req->auth->phone,
            ]);

            DB::commit();
            $apiResp = Responses::success("success submit laporan penjemputan");
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            if ($url_seal_img) {
                Storage::disk("public")->delete($url_seal_img);
            }
            if ($url_drv_armd_img) {
                Storage::disk("public")->delete($url_drv_armd_img);
            }
            if ($url_nopol_img) {
                Storage::disk("public")->delete($url_nopol_img);
            }
            if (count($url_docs_client_img) > 0) {
                foreach ($url_docs_client_img as $path) {
                    Storage::disk("public")->delete($path);
                }
            }
            if ($url_install_seal_img) {
                Storage::disk("public")->delete($url_install_seal_img);
            }
            if ($url_goods_img) {
                Storage::disk("public")->delete($url_goods_img);
            }
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_checker_submit_drop(Request $req)
    {
        $now = time();
        $url_arrived_img = null;
        $url_handover_img = null;
        // $url_do_ttd_img = []; // multiple
        $url_do_ttd_img = null; // single
        // $url_spk_img = []; // multiple
        $url_spk_img = null; // single
        try {
            $input = [
                "ord_id" => $req->ord_id,
                "ord_drop_id" => $req->ord_drop_id,
                "arrived_img_base64" => $req->arrived_img_base64,
                "handover_img_base64" => $req->handover_img_base64,
                "do_ttd_img_base64" => $req->do_ttd_img_base64,
                "spk_img_base64" => $req->spk_img_base64,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "ord_drop_id" => "nullable|integer|not_in:0",
                "arrived_img_base64" => "required|string",
                "handover_img_base64" => "required|string",
                "do_ttd_img_base64" => "required|string",
                "spk_img_base64" => "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"]);
            }

            $order = Orders::showOrder([
                "id" => $req->ord_id,
                "get_stts_checker" => 1,
                // 'chk_id' => $req->auth->uid,
            ]);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if (
                $order[0]->status === Orders::STTS_GO ||
                $order[0]->status === Orders::STTS_ARV ||
                $order[0]->status === Orders::STTS_DROP ||
                $order[0]->status === Orders::STTS_CLIENT_PAY
            ) {
            } else {
                $apiResp = Responses::bad_input("kendaraan belum berada di zona drop");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if ($req->arrived_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->arrived_img_base64
                );
                $type = "jpeg";
                if (strpos($req->arrived_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_arrived_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/arrived_img_$now.$type";
                if (!Storage::disk("public")->put($url_arrived_img, base64_decode($clearBase64))) {
                    $apiResp = Responses::bad_request("gagal upload foto seal");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            if ($req->handover_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->handover_img_base64
                );
                $type = "jpeg";
                if (strpos($req->handover_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_handover_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/handover_img_$now.$type";
                if (!Storage::disk("public")->put($url_handover_img, base64_decode($clearBase64))) {
                    Storage::disk("public")->delete($url_arrived_img);
                    $apiResp = Responses::bad_request("gagal upload foto driver armada");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            // single
            if ($req->do_ttd_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->do_ttd_img_base64
                );
                $type = "jpeg";
                if (strpos($req->do_ttd_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_do_ttd_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/do_ttd_img_$now.$type";
                if (!Storage::disk("public")->put($url_do_ttd_img, base64_decode($clearBase64))) {
                    Storage::disk("public")->delete($url_arrived_img);
                    Storage::disk("public")->delete($url_handover_img);
                    $apiResp = Responses::bad_request("gagal upload do dt ttd");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            // multiple
            // if ($req->do_ttd_img_base64 && count($req->do_ttd_img_base64) > 0) {
            // 	$skip = false;
            // 	foreach ($req->do_ttd_img_base64 as $i => $img) {
            // 		if ($skip) continue;
            // 		$clearBase64 = preg_replace('/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/', '', $img);
            // 		$type = 'jpeg';
            // 		if (strpos($img, 'application/pdf') !== false) $type = 'pdf';
            // 		$url_do_ttd_img[$i] = "orders/" . $order[0]->ord_id . "/pickups/" . $order[0]->ord_pck_id . "/checkers/" . $req->auth->uid . "/do_ttd_img_$now" . "_" . "$i.$type";
            // 		if (!Storage::disk('public')->put($url_do_ttd_img[$i], base64_decode($clearBase64))) {
            // 		Storage::disk('public')->delete($url_arrived_img);
            // 		Storage::disk('public')->delete($url_handover_img);
            // 		$apiResp = Responses::bad_request('gagal upload do ttd');
            // 		return (new Response($apiResp, $apiResp['meta']['code']));
            // 		}
            // 	}
            // }
            // single
            if ($req->spk_img_base64) {
                $clearBase64 = preg_replace(
                    "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                    "",
                    $req->spk_img_base64
                );
                $type = "jpeg";
                if (strpos($req->spk_img_base64, "application/pdf") !== false) {
                    $type = "pdf";
                }
                $url_spk_img =
                    "orders/" .
                    $order[0]->ord_id .
                    "/pickups/" .
                    $order[0]->ord_pck_id .
                    "/checkers/" .
                    $req->auth->uid .
                    "/spk_img_$now.$type";
                if (!Storage::disk("public")->put($url_spk_img, base64_decode($clearBase64))) {
                    Storage::disk("public")->delete($url_arrived_img);
                    Storage::disk("public")->delete($url_handover_img);
                    Storage::disk("public")->delete($url_do_ttd_img);
                    $apiResp = Responses::bad_request("gagal upload foto surat jalan di ttd");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            // multiple

            // kalau devices portable di lepas manual
            DB::beginTransaction();

            $updtOrd = [
                "status" => Orders::STTS_CLIENT_PAY,
                "arrived_at" => $order[0]->arrived_at ? $order[0]->arrived_at : $now,
                "chk_stts" => Orders::CHK_STTS_HAS_DROP,
            ];

            $checkPaidOff = Finance::checkJustPaidOff($order[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;
            }
            if ($checkPaidOff["invc_vdr_paid"] === 1 || $checkPaidOff["invc_vdr_paid"] === 2) {
                if (
                    $order[0]->status === Orders::STTS_GO ||
                    $order[0]->status === Orders::STTS_ARV ||
                    $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($order[0]->ord_id, $updtOrd);
            }

            OrdersDrops::updt($order[0]->ord_drop_id, [
                // drop_* => dicomment pas tracking udah jalan
                "drop_at" => $order[0]->drop_at ? $order[0]->drop_at : $now, // leave_at
                "drop_enter_at" => $order[0]->drop_enter_at ? $order[0]->drop_enter_at : $now,
                "drop_leave_at" => $order[0]->drop_leave_at ? $order[0]->drop_leave_at : $now,
                "stts_drop" => OrdersDrops::STTS_DROPED,
                "chk_id" => $req->auth->uid,
                "chk_at" => $now,
                "chk_stts" => OrdersDrops::CHK_STTS_SUBMIT,
                "chk_arrived_img" => $url_arrived_img,
                "chk_handover_img" => $url_handover_img,
                "chk_do_ttd_img" => $url_do_ttd_img,
                "chk_spk_img" => $url_spk_img,
                "chk_name" => $req->auth->first_name,
                "chk_mail" => $req->auth->email,
                "chk_addr" => $req->auth->fulladdress,
                "chk_phone_code" => $req->auth->phone_code,
                "chk_phone_val" => $req->auth->phone,
            ]);

            // kalau sudah selesai drop vhc & driver bisa order lagi
            $vehicle = Vehicles::getVehicleById($order[0]->vhc_id);
            $updtVhc = [];
            if ($vehicle[0]->ord_ids) {
                $vhc_in_ordis = json_decode($vehicle[0]->ord_ids);
                foreach ($vhc_in_ordis as $key => $val) {
                    if ($val === $order[0]->ord_id) {
                        if (count($vhc_in_ordis) <= 1) {
                            $updtVhc = [
                                "is_in_ord" => Vehicles::IN_ORD_NO,
                                "ord_id" => 0,
                                "ord_code" => 0,
                                "ord_ids" => null,
                            ];
                        } else {
                            $updtVhc["ord_ids"] = $vhc_in_ordis;
                            array_splice($updtVhc["ord_ids"], $key, 1);
                            $updtVhc["ord_ids"] = json_encode($updtVhc["ord_ids"]);
                        }
                    }
                }
            }
            if (count($updtVhc) > 0) {
                Vehicles::updateVehicle($order[0]->vhc_id, $updtVhc);
            }
            $driver = Drivers::getDriverById($order[0]->drv_id);
            $updtDrv = [];
            if ($driver[0]->ord_ids) {
                $drv_in_ordis = json_decode($driver[0]->ord_ids);
                foreach ($drv_in_ordis as $key => $val) {
                    if ($val === $order[0]->ord_id) {
                        if (count($drv_in_ordis) <= 1) {
                            $updtDrv = [
                                "is_in_ord" => Drivers::IN_ORD_NO,
                                "ord_id" => 0,
                                "ord_code" => 0,
                                "ord_ids" => null,
                            ];
                        } else {
                            $updtDrv["ord_ids"] = $drv_in_ordis;
                            array_splice($updtDrv["ord_ids"], $key, 1);
                            $updtDrv["ord_ids"] = json_encode($updtDrv["ord_ids"]);
                        }
                    }
                }
            }
            if (count($updtDrv) > 0) {
                Drivers::updateDriver($order[0]->drv_id, $updtDrv);
            }

            DB::commit();
            $apiResp = Responses::success("success submit laporan pengantaran");
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            if ($url_arrived_img) {
                Storage::disk("public")->delete($url_arrived_img);
            }
            if ($url_handover_img) {
                Storage::disk("public")->delete($url_handover_img);
            }
            if ($url_do_ttd_img) {
                Storage::disk("public")->delete($url_do_ttd_img);
            }
            if ($url_spk_img) {
                Storage::disk("public")->delete($url_spk_img);
            }
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_checker_submit_accident(Request $req)
    {
        $now = time();
        $url_accidents_img = [];
        try {
            $input = [
                "ord_id" => $req->ord_id,
                "acdnt_loc" => $req->acdnt_loc,
                "acdnt_story" => $req->acdnt_story,
                "accidents_img_base64" => $req->accidents_img_base64,
                "acdnt_vhc_nopol" => $req->acdnt_vhc_nopol,
                "acdnt_vhc_type" => $req->acdnt_vhc_type,
                "acdnt_drv_name" => $req->acdnt_drv_name,
                "acdnt_drv_phone" => $req->acdnt_drv_phone,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "acdnt_loc" => "required|string",
                "acdnt_story" => "required|string",
                "accidents_img_base64" => "nullable|array",
                "acdnt_vhc_nopol" => "required|string",
                "acdnt_vhc_type" => "required|numeric|not_in:0",
                "acdnt_drv_name" => "required|string|max:255",
                "acdnt_drv_phone" => "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"]);
            }
            if ($req->accidents_img_base64 && count($req->accidents_img_base64) < 1) {
                $apiResp = Responses::bad_input("silahkan mengunggah foto pendukung");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $nopol = explode(" ", strtoupper($req->acdnt_vhc_nopol));
            if (count($nopol) < 3) {
                $apiResp = Responses::bad_input("Nomor polisi kendaraan tidak valid");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

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

            DB::beginTransaction();

            if ($order[0]->is_accident === Orders::IS_ACCIDENT_YES) {
                $imgs = json_decode($order[0]->ord_acdnt_imgs);
                $countImgs = count($imgs);

                if ($req->accidents_img_base64 && count($req->accidents_img_base64) > 0) {
                    $skip = false;
                    foreach ($req->accidents_img_base64 as $i => $img) {
                        if ($skip) {
                            continue;
                        }
                        $clearBase64 = preg_replace(
                            "/^data:(image|application)\/(png|jpg|jpeg|pdf);base64,/",
                            "",
                            $img
                        );
                        $type = "jpeg";
                        if (strpos($img, "application/pdf") !== false) {
                            $type = "pdf";
                        }
                        $imgs[$i + $countImgs] =
                            "orders/" .
                            $order[0]->ord_id .
                            "/accidents/" .
                            $order[0]->ord_acdnt_id .
                            "/accidents_img_$now" .
                            "_" .
                            "" .
                            ($i + $countImgs) .
                            ".$type";
                        if (
                            !Storage::disk("public")->put($imgs[$i + $countImgs], base64_decode($clearBase64))
                        ) {
                            $apiResp = Responses::bad_request("gagal upload mengunggah foto pendukung");
                            return new Response($apiResp, $apiResp["meta"]["code"]);
                        }
                    }
                }

                OrdersAccidents::updateAccident($order[0]->ord_acdnt_id, [
                    "accident_location" => $req->acdnt_loc,
                    "accident_story" => $req->acdnt_story,
                    "accident_imgs" => json_encode($imgs),
                    "new_nopol1" => $nopol[0],
                    "new_nopol2" => $nopol[1],
                    "new_nopol3" => $nopol[2],
                    "new_vhc_type_id" => $req->acdnt_vhc_type,
                    "new_drv_name" => $req->acdnt_drv_name,
                    "new_drv_phone_val" => (int) $req->acdnt_drv_phone,
                ]);
            } else {
                $input = [
                    "accidents_img_base64" => $req->accidents_img_base64,
                ];
                $rulesInput = [
                    "accidents_img_base64" => "required|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"]);
                }

                Orders::updateOrder($order[0]->ord_id, [
                    "is_accident" => Orders::IS_ACCIDENT_YES,
                ]);

                $aid = OrdersAccidents::addAccident([
                    "ord_id" => $order[0]->ord_id,
                    "ord_code" => $order[0]->ord_code,
                    "accident_location" => $req->acdnt_loc,
                    "accident_story" => $req->acdnt_story,
                    "accident_imgs" => json_encode($url_accidents_img),
                    "new_vhc_id" => $order[0]->vhc_id,
                    "new_nopol1" => $nopol[0],
                    "new_nopol2" => $nopol[1],
                    "new_nopol3" => $nopol[2],
                    "old_nopol1" => $order[0]->vhc_nopol1,
                    "old_nopol2" => $order[0]->vhc_nopol2,
                    "old_nopol3" => $order[0]->vhc_nopol3,
                    "new_vhc_type_id" => $req->acdnt_vhc_type,
                    "old_vhc_type_id" => $order[0]->vhc_type_id,
                    "new_drv_name" => $req->acdnt_drv_name,
                    "new_drv_phone_val" => (int) $req->acdnt_drv_phone,
                    "old_drv_id" => $order[0]->drv_id,
                    "old_drv_name" => $order[0]->drv_name,
                    "old_drv_phone_code" => $order[0]->drv_phone_code,
                    "old_drv_phone_val" => $order[0]->drv_phone_val,
                    "crt" => $now,
                    "crt_by" => $req->auth->uid,
                    "updt" => $now,
                    "updt_by" => $req->auth->uid,
                ]);

                if ($req->accidents_img_base64 && count($req->accidents_img_base64) > 0) {
                    $skip = false;
                    foreach ($req->accidents_img_base64 as $i => $img) {
                        if ($skip) {
                            continue;
                        }
                        $url_accidents_img[$i] =
                            "orders/" .
                            $order[0]->ord_id .
                            "/accidents/" .
                            $aid .
                            "/accidents_img_$now" .
                            "_" .
                            "$i.jpeg";
                        if (!Storage::disk("public")->put($url_accidents_img[$i], base64_decode($img))) {
                            $apiResp = Responses::bad_request("gagal upload mengunggah foto pendukung");
                            return new Response($apiResp, $apiResp["meta"]["code"]);
                        }
                    }
                }

                OrdersAccidents::updateAccident($aid, [
                    "accident_imgs" => json_encode($url_accidents_img),
                ]);
            }

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

    public function api_checker_aprv_pck(Request $req)
    {
        $now = time();
        try {
            $input = [
                "ord_id" => $req->ord_id,
                "ord_pck_id" => $req->ord_pck_id,
                "is_aprv_pck" => $req->is_aprv_pck,
                "ord_pck_drop_id" => $req->ord_pck_drop_id,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "ord_pck_drop_id" => "required|integer|not_in:0",
                "ord_pck_id" => "required|integer|not_in:0",
                "is_aprv_pck" => "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_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"]);
            }

            $firstCheckpoint = OrdersCheckpoints::listCheckpoints([
                "sort" => 1,
                "ord_id" => $order[0]->ord_id,
            ]);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("checkpoint not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            /**
             * approval checker (validasi 4 kondisi)
             * 	Lokasi GPS kendaraan harus didalam zona pickup (GPS Tracker GT06, EElink)
             * 	Lokasi GPS App tracker harus didalam zona pickup (Smartphone driver apps)
             * 	Lokasi GPS kendaraan dan GPS App Tracker harus match
             * 	DONE Driver harus mengunggah foto sampai step 4
             */

            $lastLocDriverAps = Tracks::gpsLocsAddr([
                "source" => Tracks::SOURCE_SMARTPHONE,
                "drv_id" => $order[0]->drv_id,
                "order_by" => " tr.id DESC",
                "limit" => 1,
            ]);
            if (count($lastLocDriverAps) < 1) {
                $apiResp = Responses::bad_request("Lokasi GPS App Tracker tidak didalam zona pickup");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $drvAppInsideCircle = Zone::insideOrdZoneCircle(
                $lastLocDriverAps[0]->latitude,
                $lastLocDriverAps[0]->longitude,
                ["zid" => $order[0]->ord_pck_zone_id]
            );
            $drvAppInsideShape = Zone::insideOrdZoneShape(
                $lastLocDriverAps[0]->latitude,
                $lastLocDriverAps[0]->longitude,
                ["zid" => $order[0]->ord_pck_zone_id]
            );
            if (count($drvAppInsideCircle) < 1 && count($drvAppInsideShape) < 1) {
                $apiResp = Responses::bad_request("Lokasi GPS App Tracker tidak didalam zona pickup");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            // $lastLocGpsTracker = Tracks::gpsLocsAddr(['source' => Tracks::SOURCE_GPS_TRACKER, 'vhc_id' => $order[0]->vhc_id, 'order_by' => ' tr.id DESC', 'limit' => 1]);
            // if (count($lastLocGpsTracker) < 1) {
            // 	$apiResp = Responses::bad_request('Lokasi GPS Kendaraan tidak didalam zona pickup');
            // 	return (new Response($apiResp, $apiResp['meta']['code']));
            // }
            // $gpsTrackerInsideCircle = Zone::insideOrdZoneCircle($lastLocGpsTracker[0]->latitude, $lastLocGpsTracker[0]->longitude, ['zid' => $order[0]->ord_pck_zone_id]);
            // $gpsTrackerInsideShape = Zone::insideOrdZoneShape($lastLocGpsTracker[0]->latitude, $lastLocGpsTracker[0]->longitude, ['zid' => $order[0]->ord_pck_zone_id]);
            // if (count($gpsTrackerInsideCircle) < 1 && count($gpsTrackerInsideShape) < 1) {
            // 	$apiResp = Responses::bad_request('Lokasi GPS Kendaraan tidak didalam zona pickup');
            // 	return (new Response($apiResp, $apiResp['meta']['code']));
            // }

            // $distance = Helper::haversineGreatCircleDistance($lastLocDriverAps[0]->latitude, $lastLocDriverAps[0]->longitude, $lastLocGpsTracker[0]->latitude, $lastLocGpsTracker[0]->longitude);
            // // more than 100 meters
            // if ($distance > 100) {
            // 	$apiResp = Responses::bad_request('Lokasi GPS kendaraan dan GPS App Tracker harus match');
            // 	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();

            $insOrdersAItems = [
                "ord_id" => $order[0]->ord_id,
                "ord_code" => $order[0]->ord_code,
                "flow_type" => OrdersAItems::FLOW_TYPE_PAYMENT,
                "cash_type" => OrdersAItems::TYPE_CASH_OUT,
                "a_item_type" => OrdersAItems::A_TYPE_SECONDARY,
                "unit_id" => 0,
                "unit_type" => UnitTypes::UNIT_TYPE_UNIT,
                "amt_base_flat" => $firstCheckpoint[0]->pocket_total,
                "unit_qty" => 0,
                "amt_tax_type" => 0,
                "amt_tax_ppn_percent" => 0,
                "amt_tax_ppn_flat" => 0,
                "amt_tax_pph_percent" => 0,
                "amt_tax_pph_flat" => 0,
                "amt_total_tax_flat" => 0,
                "amt_result_flat" => $firstCheckpoint[0]->pocket_total,
                "amt_total_flat" => $firstCheckpoint[0]->pocket_total,
                "only_vdr" => OrdersAItems::ONLY_VDR_YES,
                "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,
                "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,
                "desc" => "Uang Saku Driver di " . $firstCheckpoint[0]->pck_name,
            ];

            $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;
            }
            OrdersAItems::add($insOrdersAItems);

            OrdersPckDrop::updt($req->ord_pck_drop_id, [
                "stts" => OrdersPckDrop::STTS_DELIVERY_OTW_DROP,
                "is_aprv_pck" => OrdersPckDrop::IS_APRV_YES,
                "aprv_pck_by" => $req->auth->id,
                "aprv_pck_at" => $now,
            ]);

            $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" => $firstCheckpoint[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" => $firstCheckpoint[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 > $firstCheckpoint[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" => $firstCheckpoint[0]->id,
                            "amount" => $firstCheckpoint[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($firstCheckpoint[0]->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('approval ditolak. 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" => $firstCheckpoint[0]->id,
                            "amount" => $firstCheckpoint[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($firstCheckpoint[0]->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-" . $firstCheckpoint[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" => $firstCheckpoint[0]->id,
                        "amount" => $firstCheckpoint[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($firstCheckpoint[0]->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('approval ditolak. 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($firstCheckpoint[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($firstCheckpoint[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("persetujuan diterima");
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    // before approval checker
    public function api_recreate_pocket(Request $req)
    {
        $now = time();
        try {
            $input = [
                "ord_id" => $req->ord_id,
                "pocket_id" => $req->pocket_id,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "pocket_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"]);
            }

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

            $pocket = PocketMoney::showPocketById($req->pocket_id);
            if (count($pocket) < 1) {
                $apiResp = Responses::not_found("uang saku belum dipilih");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $pocket[0]->checkpoints = Checkpoints::listCheckpoints([
                "pocket_id" => $pocket[0]->id,
            ]);

            if ($pocket[0]->id === $order->pocket_id) {
                $apiResp = Responses::bad_request("uang saku tidak ada perubahan");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            DB::beginTransaction();
            OrdersPockets::updatePocket($order->ord_pocket_id, [
                // 'ord_id' => $order->ord_id,
                // 'ord_code' => $order->ord_code,
                "pocket_id" => $pocket[0]->id,
                "pocket_code" => $pocket[0]->code,
                "pocket_name" => $pocket[0]->name,
                "pck_id" => $pocket[0]->pck_id,
                "drop_id" => $pocket[0]->drop_id,
                "pocket_type" => $pocket[0]->type,
                "pocket_flow" => $pocket[0]->flow,
                "pocket_is_active" => $pocket[0]->is_active,
                "pocket_total" => $pocket[0]->total,
                // 'crt' => $now,
                // 'crt_by' => $req->auth->uid,
                "updt" => $now,
                "updt_by" => $req->auth->uid,
            ]);
            OrdersCheckpoints::deleteCheckpointByOrdPocketId($order->ord_pocket_id);
            foreach ($pocket[0]->checkpoints as $checkpoint) {
                OrdersCheckpoints::addCheckpoint([
                    "ord_id" => $order->ord_id,
                    "ord_code" => $order->ord_code,
                    "ord_pocket_id" => $order->ord_pocket_id,
                    "pocket_id" => $checkpoint->pocket_id,
                    "pck_id" => $checkpoint->pck_id,
                    "drop_id" => $checkpoint->drop_id,
                    "pocket_sort" => $checkpoint->sort,
                    "pocket_fee" => $checkpoint->pocket_fee,
                    "pocket_tol_fee" => $checkpoint->tol_fee,
                    "pocket_fuel_fee" => $checkpoint->fuel_fee,
                    "pocket_total" => $checkpoint->total,
                    "crt" => $now,
                    "crt_by" => $req->auth->uid,
                    "updt" => $now,
                    "updt_by" => $req->auth->uid,
                ]);
            }

            DB::commit();

            $apiResp = Responses::success("berhasil ganti uang saku");
            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_change_pic_invoice(Request $req)
    {
        $now = time();
        try {
            $input = [
                "ord_id" => $req->ord_id,
                "ord_client_id" => $req->ord_client_id,
                "c_pt_name" => $req->c_pt_name,
                "c_pt_addr" => $req->c_pt_addr,
                "c_pt_pic_name" => $req->c_pt_pic_name,
                "c_pt_pic_phone_val" => $req->c_pt_pic_phone_val,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "ord_client_id" => "required|integer|not_in:0",
                "c_pt_name" => "required|string",
                "c_pt_addr" => "required|string",
                "c_pt_pic_name" => "required|string",
                "c_pt_pic_phone_val" => "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"]);
            }

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

            DB::beginTransaction();
            OrdersClients::updt($order->ord_client_id, [
                "c_pt_name" => $req->c_pt_name,
                "c_pt_addr" => $req->c_pt_addr,
                "c_pt_pic_name" => $req->c_pt_pic_name,
                "c_pt_pic_phone_val" => $req->c_pt_pic_phone_val,
            ]);
            DB::commit();

            $apiResp = Responses::success("berhasil ganti pic invoice");
            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_adm_confirm_price(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
            ];
            $rulesInput = [
                "ord_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_id,
                "get_stts_checker" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $updt_stts_order = $order[0]->status;
            if (
                $order[0]->status == Orders::STTS_CLIENT_PAY ||
                $order[0]->status == Orders::STTS_VENDOR_PAYED
            ) {
            } elseif ($order[0]->status == Orders::STTS_CANCEL) {
                $apiResp = Responses::bad_input('can\'t confirm price, order is cancel');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->status == Orders::STTS_CLOSE) {
                $apiResp = Responses::bad_input('can\'t confirm price, transaction is close');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->pck_chk_stts != OrdersPickups::CHK_STTS_SUBMIT) {
                $apiResp = Responses::bad_input(
                    'can\'t confirm price, checker pickup has not submitted data'
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            // else {
            // 	$apiResp = Responses::bad_input('can\'t confirm price, order still on going');
            // 	return new Response($apiResp, $apiResp['meta']['code']);
            // }

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "is_fix_price" => Orders::IS_FIX_PRICE_YES,
                "fix_price_at" => $now,
                "fix_price_by" => $req->auth->id,
                "updt" => $now,
                "updt_by" => $req->auth->id,
            ]);

            DB::commit();
            $apiResp = Responses::success("success confirm price");
            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_adm_invc_to_client(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
            ];
            $rulesInput = [
                "ord_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_id,
                "get_stts_checker" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $updt_stts_order = $order[0]->status;
            if (
                $order[0]->status == Orders::STTS_CLIENT_PAY ||
                $order[0]->status == Orders::STTS_VENDOR_PAYED
            ) {
            } elseif ($order[0]->status == Orders::STTS_CANCEL) {
                $apiResp = Responses::bad_input('can\'t generate invoice, order is cancel');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->status == Orders::STTS_CLOSE) {
                $apiResp = Responses::bad_input('can\'t generate invoice, transaction is close');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->pck_chk_stts != OrdersPickups::CHK_STTS_SUBMIT) {
                $apiResp = Responses::bad_input(
                    'can\'t generate invoice, checker pickup has not submitted data'
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            // else {
            // 	$apiResp = Responses::bad_input('can\'t generate invoice, order still on going');
            // 	return new Response($apiResp, $apiResp['meta']['code']);
            // }

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "invc_to_client_at" => $now,
                "invc_to_client_by" => $req->auth->id,
                // 'status' => $updt_stts_order,
                "updt" => $now,
                "updt_by" => $req->auth->id,
            ]);

            DB::commit();
            $apiResp = Responses::success("success generate invoice");
            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_adm_confirm_client_pay(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
                "ref_number" => $req->ref_number,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "ref_number" => "required|string|max:45",
            ];

            // 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_id,
                "get_stts_checker" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $updt_stts_order = $order[0]->status;
            if (
                $order[0]->status == Orders::STTS_CLIENT_PAY ||
                $order[0]->status == Orders::STTS_VENDOR_PAYED
            ) {
                if ($order[0]->confirm_vdr_pay_at != 0) {
                    $updt_stts_order = Orders::STTS_CLOSE;
                } else {
                    $updt_stts_order = Orders::STTS_VENDOR_PAYED;
                }
            } elseif ($order[0]->status == Orders::STTS_CANCEL) {
                $apiResp = Responses::bad_input('can\'t confirm payment, order is cancel');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->status == Orders::STTS_CLOSE) {
                $apiResp = Responses::bad_input('can\'t confirm payment, transaction is close');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->pck_chk_stts != OrdersPickups::CHK_STTS_SUBMIT) {
                $apiResp = Responses::bad_input(
                    'can\'t confirm payment, checker pickup has not submitted data'
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            // else {
            // 	$apiResp = Responses::bad_input('can\'t confirm payment, order still on going');
            // 	return new Response($apiResp, $apiResp['meta']['code']);
            // }

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "confirm_client_pay_at" => $now,
                "confirm_client_pay_by" => $req->auth->id,
                "confirm_client_pay_ref_number" => $req->ref_number,
                "status" => $updt_stts_order,
                "updt" => $now,
                "updt_by" => $req->auth->id,
            ]);
            OrdersClients::updt($order[0]->ord_client_id, [
                "pay_at" => $now,
                "is_pay" => OrdersClients::IS_PAYED,
            ]);
            if ($updt_stts_order === Orders::STTS_CLOSE) {
                Vehicles::updateVehicle($order[0]->vhc_id, [
                    "is_in_ord" => Vehicles::IN_ORD_NO,
                    "ord_id" => 0,
                    "ord_code" => 0,
                ]);
            }

            DB::commit();
            $apiResp = Responses::success("success confirm payment");
            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_adm_payout_to_vendor(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
            ];
            $rulesInput = [
                "ord_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_id,
                "get_stts_checker" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $updt_stts_order = $order[0]->status;
            if (
                $order[0]->status == Orders::STTS_CLIENT_PAY ||
                $order[0]->status == Orders::STTS_VENDOR_PAYED
            ) {
                // $updt_stts_order = Orders::STTS_VENDOR_PAYED;
            } elseif ($order[0]->status == Orders::STTS_CANCEL) {
                $apiResp = Responses::bad_input('can\'t generate instruction payment, order is cancel');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->status == Orders::STTS_CLOSE) {
                $apiResp = Responses::bad_input('can\'t generate instruction payment, transaction is close');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->drop_chk_stts != OrdersDrops::CHK_STTS_SUBMIT) {
                $apiResp = Responses::bad_input(
                    'can\'t generate instruction payment, checker drop has not submitted data'
                );
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            // else {
            // 	$apiResp = Responses::bad_input('can\'t generate instruction payment, order still on going');
            // 	return new Response($apiResp, $apiResp['meta']['code']);
            // }

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "payout_to_vdr_at" => $now,
                "payout_to_vdr_by" => $req->auth->id,
                // 'status' => $updt_stts_order,
                "updt" => $now,
                "updt_by" => $req->auth->id,
            ]);

            DB::commit();
            $apiResp = Responses::success("success generate instruction payment");
            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_adm_confirm_vendor_pay(Request $req)
    {
        try {
            $now = time();
            $input = [
                "ord_id" => $req->ord_id,
                "ref_number" => $req->ref_number,
            ];
            $rulesInput = [
                "ord_id" => "required|integer|not_in:0",
                "ref_number" => "required|string|max:45",
            ];

            // 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_id,
                "get_stts_checker" => 1,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $updt_stts_order = $order[0]->status;
            if (
                $order[0]->status == Orders::STTS_CLIENT_PAY ||
                $order[0]->status == Orders::STTS_VENDOR_PAYED
            ) {
                if ($order[0]->confirm_client_pay_at != 0) {
                    $updt_stts_order = Orders::STTS_CLOSE;
                }
            } elseif ($order[0]->status == Orders::STTS_CANCEL) {
                $apiResp = Responses::bad_input('can\'t confirm payout, order is cancel');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->status == Orders::STTS_CLOSE) {
                $apiResp = Responses::bad_input('can\'t confirm payout, transaction is close');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            } elseif ($order[0]->drop_chk_stts != OrdersDrops::CHK_STTS_SUBMIT) {
                $apiResp = Responses::bad_input('can\'t confirm payout, checker drop has not submitted data');
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            // else {
            // 	$apiResp = Responses::bad_input('can\'t confirm payout, order still on going');
            // 	return new Response($apiResp, $apiResp['meta']['code']);
            // }

            DB::beginTransaction();

            Orders::updateOrder($order[0]->ord_id, [
                "confirm_vdr_pay_at" => $now,
                "confirm_vdr_pay_by" => $req->auth->id,
                "confirm_vdr_pay_ref_number" => $req->ref_number,
                "status" => $updt_stts_order,
                "updt" => $now,
                "updt_by" => $req->auth->id,
            ]);
            OrdersVendors::updt($order[0]->ord_vdr_id, [
                "pay_at" => $now,
                "is_pay" => OrdersVendors::IS_PAYED,
            ]);
            if ($updt_stts_order === Orders::STTS_CLOSE) {
                Vehicles::updateVehicle($order[0]->vhc_id, [
                    "is_in_ord" => Vehicles::IN_ORD_NO,
                    "ord_id" => 0,
                    "ord_code" => 0,
                ]);
            }

            DB::commit();
            $apiResp = Responses::success("success confirm payout to vendor");
            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_delete_order(Request $req, $ord_id)
    {
        try {
            $now = time();

            $input = [
                "ord_id" => $ord_id,
            ];
            $rulesInput = [
                "ord_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" => $ord_id,
            ];
            $order = Orders::showOrder($filter);
            if (count($order) < 1) {
                $apiResp = Responses::not_found("order not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $user = Auth::user();

            DB::beginTransaction();

            // soft delete
            Orders::updateOrder($order[0]->ord_id, [
                "dlt" => $now,
                "dlt_by" => $user->id,
            ]);
            OrdersAccidents::updateAccidentByOrdId($order[0]->ord_id, [
                "dlt" => $now,
                "dlt_by" => $user->id,
            ]);
            OrdersAItems::updtByOrdId($order[0]->ord_id, [
                "dlt" => $now,
                "dlt_by" => $user->id,
            ]);
            // OrdersClients::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            // OrdersDrivers::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            // OrdersDrops::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            // OrdersInsurances::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            OrdersInvoices::updtByOrdId($order[0]->ord_id, [
                "dlt" => $now,
                "dlt_by" => $user->id,
            ]);
            // OrdersItems::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            // OrdersPickups::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            // OrdersRates::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            OrdersTermins::updtByOrdId($order[0]->ord_id, [
                "dlt" => $now,
                "dlt_by" => $user->id,
            ]);
            // OrdersVehicles::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            // OrdersVendors::updtByOrdId($order[0]->ord_id, ['dlt'=>$now,'dlt_by'=>$user->id]);
            OrdersPckDrop::updtByOrdId($order[0]->ord_id, [
                "dlt" => $now,
                "dlt_by" => $user->id,
            ]);
            OrdersPockets::updtByOrdId($order[0]->ord_id, [
                "dlt" => $now,
                "dlt_by" => $user->id,
            ]);
            OrdersCheckpoints::updtByOrdId($order[0]->ord_id, [
                "dlt" => $now,
                "dlt_by" => $user->id,
            ]);

            DB::commit();

            $apiResp = Responses::success("success delete order");
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }
}
