<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use App\Models\OrdersVendors;
use App\Models\Users;
use App\Models\Orders;
use App\Models\OrdersAItems;
use App\Models\OrdersInvoices;

class Finance extends Model
{
	public static function listBillings($filter = [])
	{
		$params = [
			OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_VDR_NO, OrdersAItems::INVC_TO_CLIENT_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,
			OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_VDR_NO, OrdersAItems::INVC_TO_CLIENT_YES, OrdersAItems::IS_PAID_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,
			OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_VDR_NO, OrdersAItems::INVC_TO_CLIENT_YES, OrdersAItems::IS_PAID_NO, OrdersAItems::IS_APRV_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,
		];
		$select_order = '';
		$join_join = '';
		$where_where = '';
		$group_by = '';

		if (isset($filter['ord_id'])) {
			$where_where .= ' AND ord.id = ?';
			$params[] = $filter['ord_id'];
		}

		if (isset($filter['start_date']) && isset($filter['end_date'])) {
			$where_where .= ' AND ord.crt BETWEEN ? AND ?';
			$params[] = $filter['start_date'];
			$params[] = $filter['end_date'];
		}

		if (isset($filter['group_by'])) {
			$group_by .= ' GROUP BY ' . $filter['group_by'];
		}

		return DB::select(
			"SELECT
		ord.id as ord_id,ord.code as ord_code,ord.status as ord_status
		,(SELECT SUM(amt_bill_total_flat) FROM t_orders_a_items WHERE dlt is null AND is_active = ? AND only_vdr = ? AND invc_to_client = ? AND is_bill_aprv = ? AND stts_merge IN (?,?) AND ord_id = ord.id) as total_billing
		,(SELECT SUM(amt_bill_total_flat) FROM t_orders_a_items WHERE dlt is null AND is_active = ? AND only_vdr = ? AND invc_to_client = ? AND is_bill_paid = ? AND is_bill_aprv = ? AND stts_merge IN (?,?) AND ord_id = ord.id) as total_payed
		,(SELECT SUM(amt_bill_total_flat) FROM t_orders_a_items WHERE dlt is null AND is_active = ? AND only_vdr = ? AND invc_to_client = ? AND is_bill_paid = ? AND is_bill_aprv = ? AND stts_merge IN (?,?) AND ord_id = ord.id) as total_remaining
		,ord.is_invc_paid,ord.invc_paid_at
		,ord_pck.pck_name,ord_pck.set_pck_at,ord_pck.pck_addr
		,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_pck.pck_prid LIMIT 1) as pck_prid_name
        ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_pck.pck_ktid LIMIT 1) as pck_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_pck.pck_kcid LIMIT 1) as pck_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_pck.pck_klid LIMIT 1) as pck_klid_name
		,ord_drop.drop_name,ord_drop.drop_addr
		,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_drop.drop_prid LIMIT 1) as drop_prid_name
        ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_drop.drop_ktid LIMIT 1) as drop_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_drop.drop_kcid LIMIT 1) as drop_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_drop.drop_klid LIMIT 1) as drop_klid_name
		,ord_c.c_name,ord_c.c_pt_name
        " . $select_order . "
        FROM t_orders as ord
        INNER JOIN t_orders_clients as ord_c ON ord.id = ord_c.ord_id
        INNER JOIN t_orders_pickups as ord_pck ON ord.id = ord_pck.ord_id
        INNER JOIN t_orders_drops as ord_drop ON ord.id = ord_drop.ord_id
        " . $join_join . "
        WHERE ord.dlt is null
		AND ord.is_active = " . Orders::IS_ACTIVE_YES . "
        " . $where_where . "
		" . $group_by . "
        ;",
			$params
		);
	}

	public static function summaryBillings($filter = [])
	{
		$params = [];
		$select_order = '';
		$join_join = '';
		$where_where = '';
		// for sum
		$join_sum = '';
		$where_sum = '';
		$params_sum_totbilling = [OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_VDR_NO, OrdersAItems::INVC_TO_CLIENT_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT];
		$params_sum_totpayed = [OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_VDR_NO, OrdersAItems::INVC_TO_CLIENT_YES, OrdersAItems::IS_PAID_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT];
		$params_sum_totremaining = [OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_VDR_NO, OrdersAItems::INVC_TO_CLIENT_YES, OrdersAItems::IS_PAID_NO, OrdersAItems::IS_APRV_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,];

		if (isset($filter['start_date']) && isset($filter['end_date'])) {
			$join_sum .= ' INNER JOIN t_orders as o ON a.ord_id = o.id';
			$where_sum .= ' AND o.crt BETWEEN ? AND ?';
			array_push($params_sum_totbilling, $filter['start_date'], $filter['end_date']);
			array_push($params_sum_totpayed, $filter['start_date'], $filter['end_date']);
			array_push($params_sum_totremaining, $filter['start_date'], $filter['end_date']);
		}

		// php spread operator was invented on 7.2
		$params_real = array_merge($params_sum_totbilling, $params_sum_totpayed, $params_sum_totremaining, $params);

		return DB::select(
			"SELECT
		-- (SELECT SUM(price) FROM t_orders WHERE dlt is null AND confirm_client_pay_at != 0) as total_billing
		-- (SELECT SUM(price) FROM t_orders WHERE dlt is null) as total_billing -- sebelum ada fitur merge
		 (SELECT SUM(amt_bill_total_flat) FROM t_orders_a_items as a $join_sum WHERE a.dlt is null AND a.is_active = ? AND a.only_vdr = ? AND a.invc_to_client = ? AND a.is_bill_aprv = ? AND a.stts_merge IN (?,?) $where_sum) as total_billing
		,(SELECT SUM(amt_bill_total_flat) FROM t_orders_a_items as a $join_sum WHERE a.dlt is null AND a.is_active = ? AND a.only_vdr = ? AND a.invc_to_client = ? AND a.is_bill_paid = ? AND a.is_bill_aprv = ? AND a.stts_merge IN (?,?) $where_sum) as total_payed
		,(SELECT SUM(amt_bill_total_flat) FROM t_orders_a_items as a $join_sum WHERE a.dlt is null AND a.is_active = ? AND a.only_vdr = ? AND a.invc_to_client = ? AND a.is_bill_paid = ? AND a.is_bill_aprv = ? AND a.stts_merge IN (?,?) $where_sum) as total_remaining
        " . $select_order . "
        FROM t_orders_a_items as ord_a
        " . $join_join . "
        WHERE ord_a.dlt is null
		AND ord_a.is_active = " . OrdersAItems::IS_ACTIVE_YES . "
        " . $where_where . "
		LIMIT 1
        ;",
			$params_real
		);
	}

	public static function listPayments($filter = [])
	{
		$params = [
			OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_CLIENT_NO, OrdersAItems::CALC_TO_VDR_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,
			OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_CLIENT_NO, OrdersAItems::CALC_TO_VDR_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::IS_PAID_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,
			OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_CLIENT_NO, OrdersAItems::CALC_TO_VDR_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::IS_PAID_NO, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,
		];
		$select_order = '';
		$join_join = '';
		$where_where = '';
		$group_by = '';

		if (isset($filter['ord_id'])) {
			$where_where .= ' AND ord.id = ?';
			$params[] = $filter['ord_id'];
		}

		if (isset($filter['start_date']) && isset($filter['end_date'])) {
			$where_where .= ' AND ord.crt BETWEEN ? AND ?';
			$params[] = $filter['start_date'];
			$params[] = $filter['end_date'];
		}

		if (isset($filter['group_by'])) {
			$group_by .= ' GROUP BY ' . $filter['group_by'];
		}

		return DB::select(
			"SELECT
		ord.id as ord_id,ord.code as ord_code,ord.status as ord_status
		,ord.group_code as ord_group_code
		,(SELECT SUM(amt_total_flat) FROM t_orders_a_items WHERE dlt is null AND is_active = ? AND only_client = ? AND calc_to_vdr = ? AND is_aprv = ? AND stts_merge IN (?,?) AND ord_id = ord.id) as total_payment
		,(SELECT SUM(amt_total_flat) FROM t_orders_a_items WHERE dlt is null AND is_active = ? AND only_client = ? AND calc_to_vdr = ? AND is_aprv = ? AND is_paid = ? AND stts_merge IN (?,?) AND ord_id = ord.id) as total_payed
		,(SELECT SUM(amt_total_flat) FROM t_orders_a_items WHERE dlt is null AND is_active = ? AND only_client = ? AND calc_to_vdr = ? AND is_aprv = ? AND is_paid = ? AND stts_merge IN (?,?) AND ord_id = ord.id) as total_remaining
		,ord.is_vdr_paid,ord.vdr_paid_at
		,ord_pck.pck_name,ord_pck.set_pck_at,ord_pck.pck_addr
		,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_pck.pck_prid LIMIT 1) as pck_prid_name
        ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_pck.pck_ktid LIMIT 1) as pck_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_pck.pck_kcid LIMIT 1) as pck_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_pck.pck_klid LIMIT 1) as pck_klid_name
		,ord_drop.drop_name,ord_drop.drop_addr
		,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_drop.drop_prid LIMIT 1) as drop_prid_name
        ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_drop.drop_ktid LIMIT 1) as drop_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_drop.drop_kcid LIMIT 1) as drop_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_drop.drop_klid LIMIT 1) as drop_klid_name
		,ord_c.c_name,ord_c.c_pt_name
		,ord_vdr.vdr_name,ord_vdr.vdr_pt_name
        " . $select_order . "
        FROM t_orders as ord
        INNER JOIN t_orders_clients as ord_c ON ord.id = ord_c.ord_id
        INNER JOIN t_orders_pickups as ord_pck ON ord.id = ord_pck.ord_id
        INNER JOIN t_orders_drops as ord_drop ON ord.id = ord_drop.ord_id
		INNER JOIN t_orders_vendors as ord_vdr ON ord.id = ord_vdr.ord_id
        " . $join_join . "
        WHERE ord.dlt is null
		AND ord.is_active = " . Orders::IS_ACTIVE_YES . "
        " . $where_where . "
		" . $group_by . "
        ;",
			$params
		);
	}

	// admin bank tetap terkalkulasi
	// bagaimana caranya main item client tidak tecalc di pembayaran ? where column only_client is no
	public static function summaryPayments($filter = [])
	{
		// general
		$params = [];
		$select_order = '';
		$join_join = '';
		$where_where = '';
		// for sum
		$join_sum = '';
		$where_sum = '';
		$params_sum_totpayment = [OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_CLIENT_NO, OrdersAItems::CALC_TO_VDR_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT];
		$params_sum_totpayed = [OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_CLIENT_NO, OrdersAItems::CALC_TO_VDR_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::IS_PAID_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT];
		$params_sum_totremaining = [OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_CLIENT_NO, OrdersAItems::CALC_TO_VDR_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::IS_PAID_NO, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT];

		if (isset($filter['start_date']) && isset($filter['end_date'])) {
			$join_sum .= ' INNER JOIN t_orders as o ON a.ord_id = o.id';
			$where_sum .= ' AND o.crt BETWEEN ? AND ?';
			array_push($params_sum_totpayment, $filter['start_date'], $filter['end_date']);
			array_push($params_sum_totpayed, $filter['start_date'], $filter['end_date']);
			array_push($params_sum_totremaining, $filter['start_date'], $filter['end_date']);
		}

		// php spread operator was invented on 7.2
		$params_real = array_merge($params_sum_totpayment, $params_sum_totpayed, $params_sum_totremaining, $params);

		return DB::select(
			"SELECT
		-- (SELECT SUM(buy_price) FROM t_orders WHERE dlt is null) as total_payment
		 (SELECT SUM(a.amt_total_flat) FROM t_orders_a_items as a $join_sum WHERE a.dlt is null AND a.is_active = ? AND a.only_client = ? AND a.calc_to_vdr = ? AND a.is_aprv = ? AND a.stts_merge IN (?,?) $where_sum) as total_payment
		,(SELECT SUM(a.amt_total_flat) FROM t_orders_a_items as a $join_sum WHERE a.dlt is null AND a.is_active = ? AND a.only_client = ? AND a.calc_to_vdr = ? AND a.is_aprv = ? AND a.is_paid = ? AND a.stts_merge IN (?,?) $where_sum) as total_payed
		,(SELECT SUM(a.amt_total_flat) FROM t_orders_a_items as a $join_sum WHERE a.dlt is null AND a.is_active = ? AND a.only_client = ? AND a.calc_to_vdr = ? AND a.is_aprv = ? AND a.is_paid = ? AND a.stts_merge IN (?,?) $where_sum) as total_remaining
        " . $select_order . "
        FROM t_orders_a_items as ord_a
        " . $join_join . "
        WHERE ord_a.dlt is null
		AND ord_a.is_active = " . OrdersAItems::IS_ACTIVE_YES . "
        " . $where_where . "
		LIMIT 1
        ;",
			$params_real
		);
	}

	public static function listAdtItemsPayments($filter = [])
	{
		$params = [];
		$select_order = '';
		$join_join = '';
		$where_where = '';
		$group_by = '';

		if (isset($filter['is_access_by_admin'])) {
			$where_where .= ' AND crt_type = ?';
			$params[] = OrdersAItems::CRT_TYPE_ADMIN;
		}

		if (isset($filter['ord_id'])) {
			// $where_where .= ' AND ord.id = ?';
			$where_where .= ' AND ord_a_item.ord_id = ?';
			$params[] = $filter['ord_id'];
		}

		if (isset($filter['ord_ids'])) {
			$binds_ids = "";
            foreach ($filter['ord_ids'] as $k => $v) {
                $binds_ids .= "?,";
                $params[] = $v;
            }
            if (substr($binds_ids, -1) === ',') {
                $binds_ids = substr($binds_ids, 0, -1);
            }
            $where_where .= " AND ord_a_item.ord_id IN ($binds_ids)";
		}

		if (isset($filter['is_aprv'])) {
			$where_where .= ' AND ord_a_item.is_aprv = ?';
			$params[] = $filter['is_aprv'];
		}

		if (isset($filter['get_user_crt'])) {
			$select_order .= ',ucrt.first_name as ucrt_name';
			$join_join .= ' LEFT JOIN t_users as ucrt ON ord_a_item.crt_by = ucrt.id';
		}

		if (isset($filter['get_user_rjct'])) {
			$select_order .= ',urjct.first_name as urjct_name,urjct_bill.first_name as urjct_bill_name';
			$join_join .= ' LEFT JOIN t_users as urjct ON ord_a_item.rjct_by = urjct.id';
			$join_join .= ' LEFT JOIN t_users as urjct_bill ON ord_a_item.rjct_bill_by = urjct_bill.id';
		}

		$params[] = OrdersAItems::ONLY_CLIENT_NO;
		$params[] = OrdersAItems::CALC_TO_VDR_YES;
		$params[] = OrdersAItems::IS_HIDDEN_NO;
		$params[] = OrdersAItems::STTS_MERGE_NO;
		$params[] = OrdersAItems::STTS_MERGE_RESULT;

		if (isset($filter['group_by'])) {
			$group_by .= ' GROUP BY ' . $filter['group_by'];
		}

		return DB::select(
			"SELECT
		ord_a_item.id as ord_a_item_id,ord_a_item.v_termin_id,ord_a_item.ord_id,ord_a_item.ord_code
		,ord_a_item.desc,ord_a_item.a_item_type,ord_a_item.crt_type as a_item_crt_type
		,ord_a_item.crt as a_item_crt_at
		,ord_a_item.amt_base_flat,ord_a_item.unit_qty,ord_a_item.amt_tax_type,ord_a_item.amt_total_tax_flat,ord_a_item.amt_total_flat
		,ord_a_item.ddln_pay_at,ord_a_item.ddln_pay_type
		,ord_a_item.is_paid,ord_a_item.paid_at,ord_a_item.paid_method,ord_a_item.paid_by
		,ord_a_item.is_bill_paid,ord_a_item.paid_bill_at,ord_a_item.paid_bill_method,ord_a_item.paid_bill_by
		,ord_a_item.bank_name,ord_a_item.bank_short_name,ord_a_item.bank_acc_number,ord_a_item.bank_acc_name
		,ord_a_item.invc_to_client
		,ord_a_item.img_proof_submission
		,ord_a_item.is_aprv,ord_a_item.rjct_at,ord_a_item.rjct_by,ord_a_item.rjct_bill_at,ord_a_item.rjct_bill_by
		-- ,ord_a_item.is_merge_to,ord_a_item.merge_to_a_id,ord_a_item.merge_to_ord_id,ord_a_item.merge_to_ord_code,ord_a_item.merge_to_at
		-- ,ord_a_item.is_merge_from,ord_a_item.merge_from_a_id,ord_a_item.merge_from_ord_id,ord_a_item.merge_from_ord_code,ord_a_item.merge_from_at
		,ord_a_item.stts_merge,ord_a_item.merge_to_code,ord_a_item.group_merge_code,ord_a_item.merge_at
		,ord_pck.pck_name,ord_pck.set_pck_at,ord_pck.pck_addr
		-- ,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_pck.pck_prid LIMIT 1) as pck_prid_name
        -- ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_pck.pck_ktid LIMIT 1) as pck_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_pck.pck_kcid LIMIT 1) as pck_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_pck.pck_klid LIMIT 1) as pck_klid_name
		,ord_drop.drop_name,ord_drop.drop_addr,ord_drop.chk_at as drop_chk_at
		-- ,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_drop.drop_prid LIMIT 1) as drop_prid_name
        -- ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_drop.drop_ktid LIMIT 1) as drop_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_drop.drop_kcid LIMIT 1) as drop_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_drop.drop_klid LIMIT 1) as drop_klid_name
		,ord_c.c_name,ord_c.c_pt_name
        " . $select_order . "
        FROM t_orders_a_items as ord_a_item
        INNER JOIN t_orders as ord ON ord_a_item.ord_id = ord.id
        INNER JOIN t_orders_clients as ord_c ON ord.id = ord_c.ord_id
        INNER JOIN t_orders_pickups as ord_pck ON ord.id = ord_pck.ord_id
        INNER JOIN t_orders_drops as ord_drop ON ord.id = ord_drop.ord_id
        " . $join_join . "
        WHERE ord.dlt is null
		AND ord_a_item.dlt is null
		AND ord.is_active = " . Orders::IS_ACTIVE_YES . "
		AND ord_a_item.is_active = " . OrdersAItems::IS_ACTIVE_YES . "
        " . $where_where . "
		AND ord_a_item.only_client = ?
		AND ord_a_item.calc_to_vdr = ?
		AND ord_a_item.is_hidden = ?
		AND ord_a_item.stts_merge IN (?,?)
		" . $group_by . "
        ;",
			$params
		);
	}

	public static function listAdtItemsBillings($filter = [])
	{
		$params = [];
		$select_order = '';
		$join_join = '';
		$where_where = '';
		$group_by = '';

		if (isset($filter['ord_id'])) {
			$where_where .= ' AND ord.id = ?';
			$params[] = $filter['ord_id'];
		}

		if (isset($filter['is_bill_aprv'])) {
			$where_where .= ' AND ord_a_item.is_bill_aprv = ?';
			$params[] = $filter['is_bill_aprv'];
		}

		$params[] = OrdersAItems::ONLY_VDR_NO;
		$params[] = OrdersAItems::INVC_TO_CLIENT_YES;
		$params[] = OrdersAItems::IS_HIDDEN_NO;
		$params[] = OrdersAItems::STTS_MERGE_NO;
		$params[] = OrdersAItems::STTS_MERGE_RESULT;

		if (isset($filter['group_by'])) {
			$group_by .= ' GROUP BY ' . $filter['group_by'];
		}

		return DB::select(
			"SELECT
		ord_a_item.id as ord_a_item_id,ord_a_item.v_termin_id,ord_a_item.ord_id,ord_a_item.ord_code
		,ord_a_item.desc,ord_a_item.a_item_type,ord_a_item.crt_type as a_item_crt_type
		,ord_a_item.unit_type,ut.name as unit_type_name,ord_a_item.unit_qty
		,ord_a_item.amt_bill_base_flat,ord_a_item.unit_qty,ord_a_item.amt_bill_total_flat
		,ord_a_item.is_paid,ord_a_item.paid_at,ord_a_item.paid_method,ord_a_item.paid_by
		,ord_a_item.is_bill_paid,ord_a_item.paid_bill_at,ord_a_item.paid_bill_method,ord_a_item.paid_bill_by
		,ord_termin.id as c_group_termin_id,ord_termin.termin_is_paid,ord_termin.termin_paid_at
		,ord_termin.sequence as termin_sequence,ord_termin.termin_ddln_type
		,ord_termin.termin_tax_type,ord_termin.termin_tax_ppn_percent,ord_termin.termin_tax_ppn_flat,ord_termin.termin_tax_pph_percent,ord_termin.termin_tax_pph_flat
		,ord_termin.amt_bill_confirm,ord_termin.amt_bill_confirm_note
		,ord_invc.id as invc_id,ord_invc.code as invc_code
		,ord_invc.amt_disc_type as invc_disc_type,ord_invc.amt_disc_percent as invc_disc_percent,ord_invc.amt_disc_flat as invc_disc_flat
		,ord_invc.is_gnrt_invc
		,ord_a_item.is_aprv,ord_a_item.rjct_at,ord_a_item.rjct_by,ord_a_item.rjct_bill_at,ord_a_item.rjct_bill_by
		,ord_a_item.stts_merge,ord_a_item.merge_to_code,ord_a_item.group_merge_code,ord_a_item.merge_at
		,ord_pck.pck_name,ord_pck.set_pck_at,ord_pck.pck_addr
		-- ,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_pck.pck_prid LIMIT 1) as pck_prid_name
        -- ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_pck.pck_ktid LIMIT 1) as pck_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_pck.pck_kcid LIMIT 1) as pck_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_pck.pck_klid LIMIT 1) as pck_klid_name
		,ord_drop.drop_name,ord_drop.drop_addr,ord_drop.chk_at as drop_chk_at
		-- ,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_drop.drop_prid LIMIT 1) as drop_prid_name
        -- ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_drop.drop_ktid LIMIT 1) as drop_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_drop.drop_kcid LIMIT 1) as drop_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_drop.drop_klid LIMIT 1) as drop_klid_name
		,ord_c.c_id,ord_c.c_name,ord_c.c_pt_id,ord_c.c_pt_name
        " . $select_order . "
        FROM t_orders_a_items as ord_a_item
        INNER JOIN t_orders as ord ON ord_a_item.ord_id = ord.id
        INNER JOIN t_orders_clients as ord_c ON ord.id = ord_c.ord_id
        INNER JOIN t_orders_pickups as ord_pck ON ord.id = ord_pck.ord_id
        INNER JOIN t_orders_drops as ord_drop ON ord.id = ord_drop.ord_id
        INNER JOIN t_orders_termins as ord_termin ON ord_a_item.c_termin_id = ord_termin.id
		LEFT JOIN t_orders_invoices as ord_invc ON ord_termin.id = ord_invc.c_termin_id
		LEFT JOIN t_unit_types as ut ON ord_a_item.unit_type = ut.id
        " . $join_join . "
        WHERE ord.dlt is null
		AND ord_a_item.dlt is null
		AND ord.is_active = " . Orders::IS_ACTIVE_YES . "
		AND ord_a_item.is_active = " . OrdersAItems::IS_ACTIVE_YES . "
        " . $where_where . "
		AND only_vdr = ?
		AND invc_to_client = ?
		AND ord_a_item.is_hidden = ?
		AND ord_a_item.stts_merge IN (?,?)
		" . $group_by . "
        ;",
			$params
		);
	}

	public static function listLedgerBl($filter = [])
	{
		$params = [
			OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_VDR_NO, OrdersAItems::INVC_TO_CLIENT_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::IS_PAID_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,
			OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_CLIENT_NO, OrdersAItems::CALC_TO_VDR_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::IS_PAID_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT,
		];
		$select_order = '';
		$join_join = '';
		$where_where = '';
		$group_by = '';

		if (isset($filter['ord_id'])) {
			$where_where .= ' AND ord.id = ?';
			$params[] = $filter['ord_id'];
		}

		if (isset($filter['with_items'])) {
			$select_order .= "
			,ord_a_item.id as ord_a_item_id
			,ord_a_item.a_item_type,ord_a_item.desc as item_desc,ord_a_item.unit_type,unit_type.name as unit_type_name,ord_a_item.unit_qty
			,ord_a_item.amt_base_flat,ord_a_item.amt_result_flat,ord_a_item.amt_total_flat
			,ord_a_item.amt_bill_base_flat,ord_a_item.amt_bill_result_flat,ord_a_item.amt_bill_total_flat
			,ord_a_item.is_paid,ord_a_item.paid_at,ord_a_item.is_bill_paid,ord_a_item.paid_bill_at
			,ord_a_item.invc_to_client,ord_a_item.calc_to_vdr,ord_a_item.is_adm_price,ord_a_item.only_client,ord_a_item.only_vdr,ord_a_item.is_hidden,ord_a_item.is_tax,ord_a_item.is_disc
			,ord_a_item.is_aprv,ord_a_item.is_bill_aprv
			";
			$join_join .= "
			INNER JOIN t_orders_a_items as ord_a_item ON ord.id = ord_a_item.ord_id
			LEFT JOIN t_unit_types as unit_type ON ord_a_item.unit_type = unit_type.id
			";
			// perlu diperbaiki cara if di query, jika kalkulasi ke vendor maka is_aprv = , jika ke client is_bill_aprv = 1
			$where_where .= ' AND ord_a_item.dlt is null AND (ord_a_item.calc_to_vdr = ' . OrdersAItems::CALC_TO_VDR_YES . ' OR ord_a_item.invc_to_client = ' . OrdersAItems::INVC_TO_CLIENT_YES . ') AND (ord_a_item.is_aprv = ' . OrdersAItems::IS_APRV_YES . ' OR ord_a_item.is_bill_aprv = ' . OrdersAItems::IS_APRV_YES . ')';
		}

		if (isset($filter['start_date']) && isset($filter['end_date'])) {
			$where_where .= ' AND ord.crt BETWEEN ? AND ?';
			$params[] = $filter['start_date'];
			$params[] = $filter['end_date'];
		}
		
		if (isset($filter['group_by'])) {
			$group_by .= ' GROUP BY ' . $filter['group_by'];
		}

		return DB::select(
			"SELECT
		ord.id as ord_id,ord.code as ord_code,ord.status as ord_status
		,@total_in:=(SELECT SUM(amt_bill_total_flat) FROM t_orders_a_items WHERE dlt is null AND is_active = ? AND only_vdr = ? AND invc_to_client = ? AND is_bill_aprv = ? AND is_bill_paid = ? AND stts_merge IN (?,?) AND ord_id = ord.id) as total_in
		,@total_out:=(SELECT SUM(amt_total_flat) FROM t_orders_a_items WHERE dlt is null AND is_active = ? AND only_client = ? AND calc_to_vdr = ? AND is_aprv = ? AND is_paid = ? AND stts_merge IN (?,?) AND ord_id = ord.id) as total_out
		,(IFNULL(@total_in, 0) - IFNULL(@total_out, 0)) as total_bl
		,ord_pck.pck_name,ord_pck.set_pck_at,ord_pck.pck_addr
		,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_pck.pck_prid LIMIT 1) as pck_prid_name
        ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_pck.pck_ktid LIMIT 1) as pck_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_pck.pck_kcid LIMIT 1) as pck_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_pck.pck_klid LIMIT 1) as pck_klid_name
		,ord_drop.drop_name,ord_drop.drop_addr
		,(SELECT nmProvinsiKel FROM t_region WHERE kodeProv = ord_drop.drop_prid LIMIT 1) as drop_prid_name
        ,(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_drop.drop_ktid LIMIT 1) as drop_ktid_name
        -- ,(SELECT nmKecamatanKel FROM t_region WHERE kodeKec = ord_drop.drop_kcid LIMIT 1) as drop_kcid_name
        -- ,(SELECT nmKelurahan FROM t_region WHERE kodeKel = ord_drop.drop_klid LIMIT 1) as drop_klid_name
		,ord_c.c_name,ord_c.c_pt_name
		,ord_vdr.vdr_name,ord_vdr.vdr_pt_name
        " . $select_order . "
        FROM t_orders as ord
        INNER JOIN t_orders_clients as ord_c ON ord.id = ord_c.ord_id
        INNER JOIN t_orders_pickups as ord_pck ON ord.id = ord_pck.ord_id
        INNER JOIN t_orders_drops as ord_drop ON ord.id = ord_drop.ord_id
		INNER JOIN t_orders_vendors as ord_vdr ON ord.id = ord_vdr.ord_id
        " . $join_join . "
        WHERE ord.dlt is null
		AND ord.is_active = " . Orders::IS_ACTIVE_YES . "
        " . $where_where . "
		" . $group_by . "
        ;",
			$params
		);
	}

	public static function summaryLedgerBl($filter = [])
	{
		$params = [];
		$select_order = '';
		$join_join = '';
		$where_where = '';
		// for sum
		$join_sum = '';
		$where_sum = '';
		$params_sum_totin = [OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_VDR_NO, OrdersAItems::INVC_TO_CLIENT_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::IS_PAID_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT];
		$params_sum_totout = [OrdersAItems::IS_ACTIVE_YES, OrdersAItems::ONLY_CLIENT_NO, OrdersAItems::CALC_TO_VDR_YES, OrdersAItems::IS_APRV_YES, OrdersAItems::IS_PAID_YES, OrdersAItems::STTS_MERGE_NO, OrdersAItems::STTS_MERGE_RESULT];

		if (isset($filter['start_date']) && isset($filter['end_date'])) {
			$join_sum .= ' INNER JOIN t_orders as o ON a.ord_id = o.id';
			$where_sum .= ' AND o.crt BETWEEN ? AND ?';
			array_push($params_sum_totin, $filter['start_date'], $filter['end_date']);
			array_push($params_sum_totout, $filter['start_date'], $filter['end_date']);
		}

		// php spread operator was invented on 7.2
		$params_real = array_merge($params_sum_totin, $params_sum_totout, $params);

		return DB::select(
			"SELECT
		@total_in:=(SELECT SUM(amt_bill_total_flat) FROM t_orders_a_items as a $join_sum WHERE a.dlt is null AND a.is_active = ? AND a.only_vdr = ? AND a.invc_to_client = ? AND a.is_bill_aprv = ? AND a.is_bill_paid = ? AND a.stts_merge IN (?,?) $where_sum) as total_in
		,@total_out:=(SELECT SUM(amt_total_flat) FROM t_orders_a_items as a $join_sum WHERE a.dlt is null AND a.is_active = ? AND a.only_client = ? AND a.calc_to_vdr = ? AND a.is_aprv = ? AND a.is_paid = ? AND a.stts_merge IN (?,?) $where_sum) as total_out
		,(IFNULL(@total_in, 0) - IFNULL(@total_out, 0)) as total_bl
        " . $select_order . "
        FROM t_orders_a_items as ord_a
        " . $join_join . "
        WHERE ord_a.dlt is null
		AND ord_a.is_active = " . OrdersAItems::IS_ACTIVE_YES . "
        " . $where_where . "
		LIMIT 1
        ;",
			$params_real
		);
	}

	/**
	 * Baru saja pembayaran dilunaskan baik dari client / vendor
	 * false => error
	 * 0 => not paid, 1 => just paid off, 2 => paid off
	 */
	public static function checkJustPaidOff($ord_id)
	{
		$order = Orders::showOrder(['id' => $ord_id]);
		if (count($order) < 1 || $order === false) return false;
		$out = [
			'invc_paid' => 0,
			'vdr_paid' => 0,
			'invc_vdr_paid' => 0,
		];
		$currentBill = Finance::listBillings(['ord_id' => $ord_id]);
		$currentPay = Finance::listPayments(['ord_id' => $ord_id]);
		// paid off
		if ($currentBill[0]->total_billing === $currentBill[0]->total_payed || $currentPay[0]->total_payment === $currentPay[0]->total_payed) {
			if ($currentBill[0]->total_billing === $currentBill[0]->total_payed) {
				// just paid off
				if ($order[0]->is_invc_paid !== Orders::IS_PAID_YES) {
					$out['invc_paid'] = 1;
				} else {
					$out['invc_paid'] = 2;
				}
			}
			if ($currentPay[0]->total_payment === $currentPay[0]->total_payed) {
				// just paid off
				if ($order[0]->is_vdr_paid !== Orders::IS_PAID_YES) {
					$out['vdr_paid'] = 1;
				} else {
					$out['vdr_paid'] = 2;
				}
			}
			if ($currentBill[0]->total_billing === $currentBill[0]->total_payed && $currentPay[0]->total_payment === $currentPay[0]->total_payed) {
				// just paid off
				if ($out['invc_paid'] === 1 || $out['vdr_paid'] === 1) {
					$out['invc_vdr_paid'] = 1;
				} else {
					$out['invc_vdr_paid'] = 2;
				}
			}
		}
		return $out;
	}

	public static function updtChangeInvc($c_termin_id)
	{
		$ord_invc = OrdersInvoices::getByTerminId($c_termin_id);
		if ($ord_invc !== false && count($ord_invc) > 0) {
			OrdersInvoices::updt($ord_invc[0]->id, [
				'is_gnrt_invc' => OrdersInvoices::IS_GNRT_INVC_NO,
			]);
			return true;
		}
		return false;
	}

	public static function availOrdToMerge($filter = [])
	{
		$params = [];
		$select = '';
		$join = '';
		$where = '';
		$group_by = '';

		$where .= ' AND ord.stts_merge IN (?,?)';
		$params[] = OrdersAItems::STTS_MERGE_NO;
		$params[] = OrdersAItems::STTS_MERGE_RESULT;

		if (isset($filter['except_ord_id'])) {
			$where .= ' AND ord.id = ?';
			$params[] = $filter['except_ord_id'];
		}

		return DB::select(
		"SELECT
		ord.*
        " . $select . "
        FROM t_orders as ord
        " . $join . "
        WHERE ord.dlt is null
		AND ord.stts_merge = " . Orders::STTS_MERGE_NO . "
        " . $where . "
		ORDER BY ord.id DESC
		" . $group_by . "
		LIMIT 100
        ;",
			$params
		);
	}
}
