<?php
namespace App\Http\Controllers\WeChatApplet\AppletAccountControl;

use Illuminate\Http\Request;
use App\Http\Models\Api\Common;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;

// 微信小程序 -- 财务系统 -- 应收账款分析
class AppletReceivableAnalyzeController extends Controller
{
    // 列表每页显示数据个数
    protected $show_count = 10;

    // 列表
    public function index(Request $request)
    {
        // 获取当前操作账号信息
        $user_info = Common::wechatGetUserInfo($request['api_token']);

        $search_data = $request->all();
        // 会员零售统计
        if ($request['recr_client_type'] == 1) {
            $return_data = $this->memberStatistics($user_info);
            $data_info['data'][] = $return_data; //返回数据
            if ($return_data) {
                return response()->json(['code'=>200, 'msg'=>'success', 'data'=>$data_info]);
            } else {
                return response()->json(['code'=>500, 'msg'=>'error', 'data'=>'暂无数据']);
            }
        }

        // 客户单位类型统计
        $list_data = $this->searchclientUnitReceivable($user_info, $search_data, 1);
        $list_items = $list_data->items();
        if ($list_items) {
            $list_items = json_decode(json_encode($list_items), true);
            $chin_prec_id = array_filter(array_column($list_items, 'chin_prec_id')); //业务划区id
            $adm_id = array_unique(array_column($list_items, 'chun_adm_id')); //业务员账号id
            $chun_id = array_unique(array_column($list_items, 'chun_id')); //客户单位id
            // 正值
            $positive = $this->clientUnitTimeBucketPrice($user_info, 1, $chun_id);
            // 负值
            $minus = $this->clientUnitTimeBucketPrice($user_info, 2, $chun_id);

            // 30天以内(含30天) 0到30天正值
            $start_time = date('Y-m-d', strtotime('-30 day')) . ' 00:00:00'; //开始时间
            $end_time = date('Y-m-d', strtotime('-1 day')) . ' 23:59:59'; //结束时间
            $thirty_positive = $this->clientUnitTimeBucketPrice($user_info, 1, $chun_id, $start_time, $end_time);
            // 30天以内(含30天) 0到30天负值
            $thirty_minus = $this->clientUnitTimeBucketPrice($user_info, 2, $chun_id, $start_time, $end_time);

            // 31天至60天(含60天)
            $start_time = date('Y-m-d', strtotime('-60 day')) . ' 00:00:00'; //开始时间，第60天
            $end_time = date('Y-m-d', strtotime('-31 day')) . ' 23:59:59'; //结束时间，第31天
            $sixty_positive = $this->clientUnitTimeBucketPrice($user_info, 1, $chun_id, $start_time, $end_time);
            // 31天至60天(含60天)
            $sixty_minus = $this->clientUnitTimeBucketPrice($user_info, 2, $chun_id, $start_time, $end_time);

            // 61天至90天(含90天)
            $start_time = date('Y-m-d', strtotime('-90 day')) . ' 00:00:00'; //开始时间
            $end_time = date('Y-m-d', strtotime('-61 day')) . ' 23:59:59'; //结束时间
            $ninety_positive = $this->clientUnitTimeBucketPrice($user_info, 1, $chun_id, $start_time, $end_time);
            // 61天至90天(含90天)
            $ninety_minus = $this->clientUnitTimeBucketPrice($user_info, 2, $chun_id, $start_time, $end_time);

            // 91天至180天(含180天)
            $start_time = date('Y-m-d', strtotime('-180 day')) . ' 00:00:00'; //开始时间
            $end_time = date('Y-m-d', strtotime('-91 day')) . ' 23:59:59'; //结束时间
            $great_positive = $this->clientUnitTimeBucketPrice($user_info, 1, $chun_id, $start_time, $end_time);
            // 91天至180天(含180天)
            $great_minus = $this->clientUnitTimeBucketPrice($user_info, 2, $chun_id, $start_time, $end_time);

            // 180以前
            $start_time = date('Y-m-d', strtotime('-180 day')) . ' 00:00:00'; //开始时间
            $greater_positive = $this->clientUnitTimeBucketPrice($user_info, 1, $chun_id, $start_time);
            // 180以前
            $greater_minus = $this->clientUnitTimeBucketPrice($user_info, 2, $chun_id, $start_time);

            foreach ($list_items as $key => $value) {
                // 计算余额
                $list_items[$key]['nowprice'] = $this->clientUnitCalculatePrice($positive, $minus, $value['chun_id']);

                // 计算30天以内(含30天)余额
                $list_items[$key]['thirty'] = $this->clientUnitCalculatePrice($thirty_positive, $thirty_minus, $value['chun_id']);
                // 计算比例
                $list_items[$key]['thirty_ratio'] = $this->computeRatio($list_items[$key]['nowprice'], $list_items[$key]['thirty']);

                // 31天至60天(含60天)
                $list_items[$key]['sixty'] = $this->clientUnitCalculatePrice($sixty_positive, $sixty_minus, $value['chun_id']);
                // 计算比例
                $list_items[$key]['sixty_ratio'] = $this->computeRatio($list_items[$key]['nowprice'], $list_items[$key]['sixty']);

                // 61天至90天(含90天)
                $list_items[$key]['ninety'] = $this->clientUnitCalculatePrice($ninety_positive, $ninety_minus, $value['chun_id']);
                // 计算比例
                $list_items[$key]['ninety_ratio'] = $this->computeRatio($list_items[$key]['nowprice'], $list_items[$key]['ninety']);

                // 91天至180天(含180天)
                $list_items[$key]['great'] = $this->clientUnitCalculatePrice($great_positive, $great_minus, $value['chun_id']);
                // 计算比例
                $list_items[$key]['great_ratio'] = $this->computeRatio($list_items[$key]['nowprice'], $list_items[$key]['great']);

                // 180以前
                $list_items[$key]['greater'] = $this->clientUnitCalculatePrice($greater_positive, $greater_minus, $value['chun_id']);
                // 计算比例
                $list_items[$key]['greater_ratio'] = $this->computeRatio($list_items[$key]['nowprice'], $list_items[$key]['greater']);
            }

            // 查找业务划区数据
            $find_precincts = DB::table('precincts')
                ->whereIn('prec_id', $chin_prec_id)
                ->get(['prec_id', 'prec_name']);
            $data_info['find_precincts'] = $find_precincts; //业务划区
            // 查找业务员
            $data_info['adm_info'] = DB::table('admin')
                ->whereIn('adm_id', $adm_id)
                ->get(['adm_id', 'adm_name']);
        } else {
            $type_info = [];
            $adm_info = [];
        }

        $data_info['current_page'] = $list_data->currentPage();  //当前页面页码
        $data_info['last_page'] = $list_data->lastPage();        //表示最后一页的页码
        $data_info['total'] = $list_data->total();               //总数据个数
        $data_info['current_number'] = $this->show_count;        //一页显示多少个
        $data_info['data'] = $list_items;                        //返回数据

        if ($list_data) {
            return response()->json(['code'=>200, 'msg'=>'success', 'data'=>$data_info]);
        } else {
            return response()->json(['code'=>500, 'msg'=>'error', 'data'=>'暂无数据']);
        }
    }

    /**
     * [searchclientUnitReceivable 查询应收应付的客户单位]
     * @param  [type] $user_info [用户信息]
     * @param  [type] $type      [类型：1列表查询2导出]
     * @return [type]            [description]
     */
    private function searchclientUnitReceivable($user_info, $search_data, $type)
    {
        $list_data = DB::table('receivable_credit as rc')
            ->leftJoin('channel_unit as cu', 'cu.chun_id', '=', 'rc.recr_client_id') //应收账款表
            ->leftJoin('channel_info as ci', 'ci.chin_chun_id', '=', 'cu.chun_id')
            ->where('recr_cid', $user_info->adm_cid)
            ->where('recr_shop_id', $user_info->adm_shop_id)
            ->where('recr_client_type', 2) //客户类型：1会员零售2来往单位
            ->where('recr_belongs_id', '=', 0)
            ->where('recr_state', '!=', 2) //状态：1未确认2已确认3已收款4已付款
            ->where(function ($query) use ($search_data) { //单位名称
                if (!empty($search_data['chun_name'])) {
                    $query->where('chun_unit_name', 'like', '%' . $search_data['chun_name'] . '%');
                }
            })
            ->where(function ($query) use ($search_data) { //客户电话
                if (!empty($search_data['chin_zoning'])) {
                    $query->where('chin_zoning', 'like', '%' . $search_data['chin_zoning'] . '%');
                }
            })
            ->where(function ($query) use ($search_data) { //业务员
                if (!empty($search_data['chun_search_letter'])) {
                    $query->where('chun_search_letter', $search_data['chun_search_letter']);
                }
            })
            ->where(function ($query) use ($search_data) { //业务划区id
                if (!empty($search_data['chin_prec_id'])) {
                    $query->where('chin_prec_id', $search_data['chin_prec_id']);
                }
            })
            ->where(function ($query) use ($search_data) { //客户单位id
                if (!empty($search_data['recr_client_id'])) {
                    $query->where('recr_client_id', $search_data['recr_client_id']);
                }
            })
            ->where(function ($query) use ($search_data) { //业务员id
                if (!empty($search_data['chun_adm_id'])) {
                    $query->where('chun_adm_id', $search_data['chun_adm_id']);
                }
            })
            ->where(function ($query) use ($search_data) { //结算方式1账期2现结
                if (!empty($search_data['chun_payment_way'])) {
                    $query->where('chun_payment_way', $search_data['chun_payment_way']);
                }
            })
            ->select(DB::raw('chun_id, chun_unit_name, chun_search_letter, chun_payment_way, chin_prec_id, chun_adm_id'))
            ->groupBy('chun_id');
        if ($type == 1) {
            $list_data = $list_data->paginate($this->show_count);
        } else {
            $list_data = $list_data->get()->toArray();
        }
        return $list_data;
    }

    /**
     * [clientUnitTimeBucketPrice 统计客户单位时间段应收应付金额]
     * @param  [type] $user_info       [用户信息]
     * @param  [type] $recr_plus_minus [金额正负：1正值2负值]
     * @param  [type] $chun_id         [客户单位id，数组]
     * @param  [type] $start_time      [开始时间]
     * @param  [type] $end_time        [结束时间]
     * @return [type]                  [description]
     */
    private function clientUnitTimeBucketPrice($user_info, $recr_plus_minus, $chun_id, $start_time = null, $end_time = null)
    {
        $time_bucket_price  = collect(DB::table('receivable_credit')
            ->where('recr_cid', $user_info->adm_cid)
            ->where('recr_shop_id', $user_info->adm_shop_id)
            ->where('recr_plus_minus', $recr_plus_minus) //金额正负：1正值2负值
            ->where('recr_client_type', 2) //客户类型：1会员零售2来往单位
            ->where('recr_belongs_id', '=', 0)
            ->where('recr_state', '!=', 2) //状态：1未确认2已确认3已收款4已付款
            ->whereIn('recr_client_id', $chun_id)
            ->where(function ($query) use ($start_time, $end_time) {
                if (!empty($start_time) && !empty($end_time)) {
                    $query->whereBetween('recr_order_time', [$start_time, $end_time]);
                } elseif (!empty($start_time)) {
                    // 180天以上
                    $query->where('recr_order_time', '<', $start_time);
                }
            })
            ->select(DB::Raw('sum(recr_settle_price) as recr_settle_price,sum(recr_yet_receipt) as recr_yet_receipt,sum(recr_zero_price) as recr_zero_price,recr_client_id'))
            ->groupBy('recr_client_id')
            ->get())->keyBy('recr_client_id')->toArray();
        return $time_bucket_price;
    }

    /**
     * [memberStatistics 会员零售统计]
     * @param  [type] $user_info [用户信息]
     * @return [type]            [description]
     */
    private function memberStatistics($user_info)
    {
        // 应收应付的正数金额
        $positive_price = $this->memberTimeBucketPrice($user_info, 1);
        // 应收应付的负数金额
        $minus_price = $this->memberTimeBucketPrice($user_info, 2);
        // 计算当前余额
        $nowprice = $this->memberCalculatePrice((array)$positive_price, (array)$minus_price);

        // 30天以内(含30天) 0到30天正值
        $start_time = date('Y-m-d', strtotime('-30 day')) . ' 00:00:00'; //开始时间
        $end_time = date('Y-m-d', strtotime('-1 day')) . ' 23:59:59'; //结束时间
        $thirty_positive = $this->memberTimeBucketPrice($user_info, 1, $start_time, $end_time);
        // 30天以内(含30天) 0到30天负值
        $thirty_minus = $this->memberTimeBucketPrice($user_info, 2, $start_time, $end_time);
        // 计算余额
        $thirty = $this->memberCalculatePrice((array)$thirty_positive, (array)$thirty_minus);
        // 计算比例
        $thirty_ratio = $this->computeRatio($nowprice, $thirty);

        // 31天至60天(含60天)
        $start_time = date('Y-m-d', strtotime('-60 day')) . ' 00:00:00'; //开始时间，第60天
        $end_time = date('Y-m-d', strtotime('-31 day')) . ' 23:59:59'; //结束时间，第31天
        $sixty_positive = $this->memberTimeBucketPrice($user_info, 1, $start_time, $end_time);
        // 31天至60天(含60天) 0到30天负值
        $sixty_minus = $this->memberTimeBucketPrice($user_info, 2, $start_time, $end_time);
        // 计算余额
        $sixty = $this->memberCalculatePrice((array)$sixty_positive, (array)$sixty_minus);
        // 计算比例
        $sixty_ratio = $this->computeRatio($nowprice, $sixty);

        // 61天至90天(含90天)
        $start_time = date('Y-m-d', strtotime('-90 day')) . ' 00:00:00'; //开始时间
        $end_time = date('Y-m-d', strtotime('-61 day')) . ' 23:59:59'; //结束时间
        $ninety_positive = $this->memberTimeBucketPrice($user_info, 1, $start_time, $end_time);
        // 61天至90天(含90天)
        $ninety_minus = $this->memberTimeBucketPrice($user_info, 2, $start_time, $end_time);
        // 计算余额
        $ninety = $this->memberCalculatePrice((array)$ninety_positive, (array)$ninety_minus);
        // 计算比例
        $ninety_ratio = $this->computeRatio($nowprice, $ninety);

        // 91天至180天(含180天)
        $start_time = date('Y-m-d', strtotime('-180 day')) . ' 00:00:00'; //开始时间
        $end_time = date('Y-m-d', strtotime('-91 day')) . ' 23:59:59'; //结束时间
        $great_positive = $this->memberTimeBucketPrice($user_info, 1, $start_time, $end_time);
        // 91天至180天(含180天)
        $great_minus = $this->memberTimeBucketPrice($user_info, 2, $start_time, $end_time);
        // 计算余额
        $great = $this->memberCalculatePrice((array)$great_positive, (array)$great_minus);
        // 计算比例
        $great_ratio = $this->computeRatio($nowprice, $great);

        // 180天以上
        $start_time = date('Y-m-d', strtotime('-180 day')) . ' 00:00:00'; //开始时间
        $greater_positive = $this->memberTimeBucketPrice($user_info, 1, $start_time);
        // 180天以上
        $greater_minus = $this->memberTimeBucketPrice($user_info, 2, $start_time);
        // 计算余额
        $greater = $this->memberCalculatePrice((array)$greater_positive, (array)$greater_minus);
        // 计算比例
        $greater_ratio = $this->computeRatio($nowprice, $greater);

        $return_data['nowprice'] = $nowprice; //当前余额
        $return_data['thirty'] = $thirty; //30天以内余额（含30天）
        $return_data['thirty_ratio'] = $thirty_ratio; //三十天以内比例（含30天）
        $return_data['sixty'] = $sixty; //31天到60天余额（含60天）
        $return_data['sixty_ratio'] = $sixty_ratio; //31天到60天比例（含60天）
        $return_data['ninety'] = $ninety; //61天到90天余额（含90天）
        $return_data['ninety_ratio'] = $ninety_ratio; //61天到90天比例（含90天）
        $return_data['great'] = $great; //91天到180天余额（含180天）
        $return_data['great_ratio'] = $great_ratio; //91天到180天比例（含180天）
        $return_data['greater'] = $greater; //180天以上余额
        $return_data['greater_ratio'] = $greater_ratio; //180天以上比例
        return $return_data;
    }

    /**
     * [memberTimeBucketPrice 统计会员零售时间段应收应付金额]
     * @param  [type] $user_info       [用户信息]
     * @param  [type] $recr_plus_minus [金额正负：1正值2负值]
     * @param  [type] $start_time      [开始时间]
     * @param  [type] $end_time        [结束时间]
     * @return [type]                  [description]
     */
    private function memberTimeBucketPrice($user_info, $recr_plus_minus, $start_time = null, $end_time = null)
    {
        $time_bucket_price = DB::table('receivable_credit as rc')
            ->where('recr_cid', $user_info->adm_cid)
            ->where('recr_shop_id', $user_info->adm_shop_id)
            ->where('recr_plus_minus', $recr_plus_minus) //金额正负：1正值2负值
            ->where('recr_client_type', 1) //客户类型：1会员零售2来往单位
            ->where('recr_belongs_id', '=', 0)
            ->where('recr_state', '!=', 2) //状态：1未确认2已确认3已收款4已付款
            ->where(function ($query) use ($start_time, $end_time) {
                if (!empty($start_time) && !empty($end_time)) {
                    $query->whereBetween('recr_order_time', [$start_time, $end_time]);
                } elseif (!empty($start_time)) {
                    // 180天以上
                    $query->where('recr_order_time', '<', $start_time);
                }
            })
            ->select(DB::raw('sum(recr_settle_price) as recr_settle_price,sum(recr_actual_price) as recr_actual_price,sum(recr_yet_receipt) as recr_yet_receipt,sum(recr_zero_price) as recr_zero_price'))
            ->first();
        return $time_bucket_price;
    }

    /**
     * [computeRatio 计算金额比例]
     * @param  [type] $denominator [分母]
     * @param  [type] $numerator   [分子]
     * @return [type]              [description]
     */
    private function computeRatio($denominator, $numerator)
    {
        if (empty($denominator) && empty($numerator)) {
            $ratio = 0;
        } else {
            if ($denominator == 0) {
                $ratio = 0;
            } else {
                $ratio = round($numerator / $denominator, 2) * 100;
            }
        }
        return $ratio;
    }

    /**
     * [memberCalculatePrice 会员零售计算金额]
     * @param  [type] $positive_price [正数金额]
     * @param  [type] $minus_price    [负数金额]
     * @return [type]                 [description]
     */
    private function memberCalculatePrice($positive_price, $minus_price)
    {
        // recr_settle_price 结算金额
        $positive_settle_price = isset($positive_price['recr_settle_price']) ? $positive_price['recr_settle_price'] : 0;
        $minus_settle_price = isset($minus_price['recr_settle_price']) ? $minus_price['recr_settle_price'] : 0;
        $settle_price = $positive_settle_price - $minus_settle_price; //当前的结算金额

        // recr_yet_receipt 已收金额
        $positive_yet_receipt = isset($positive_price['recr_yet_receipt']) ? $positive_price['recr_yet_receipt'] : 0;
        $minus_yet_receipt = isset($minus_price['recr_yet_receipt']) ? $minus_price['recr_yet_receipt'] : 0;
        $yet_receipt  =  $positive_yet_receipt - $minus_yet_receipt;

        // recr_zero_price 抹零金额
        $positive_zero_price = isset($positive_price['recr_zero_price']) ? $positive_price['recr_zero_price'] : 0;
        $minus_zero_price = isset($minus_price['recr_zero_price']) ? $minus_price['recr_zero_price'] : 0;
        $zero_price = $positive_zero_price - $minus_zero_price;

        // 当前的欠收金额 = 结算金额 - 已收金额 - 抹零金额
        $bad_crop_price = $settle_price - $yet_receipt - $zero_price;
        return $bad_crop_price;
    }

    /**
     * [clientUnitCalculatePrice 客户单位计算金额]
     * @param  [type] $positive_price [正数金额]
     * @param  [type] $minus_price    [负数金额]
     * @return [type]                 [description]
     */
    private function clientUnitCalculatePrice($positive_price, $minus_price, $chun_id)
    {
        // recr_settle_price 结算金额
        $positive_settle_price = isset($positive_price[$chun_id]->recr_settle_price) ? $positive_price[$chun_id]->recr_settle_price : 0;
        $minus_settle_price = isset($minus_price[$chun_id]->recr_settle_price) ? $minus_price[$chun_id]->recr_settle_price : 0;
        $settle_price = $positive_settle_price - $minus_settle_price; //当前的结算金额

        // recr_yet_receipt 已收金额
        $positive_yet_receipt = isset($positive_price[$chun_id]->recr_yet_receipt) ? $positive_price[$chun_id]->recr_yet_receipt : 0;
        $minus_yet_receipt = isset($minus_price[$chun_id]->recr_yet_receipt) ? $minus_price[$chun_id]->recr_yet_receipt : 0;
        $yet_receipt  =  $positive_yet_receipt - $minus_yet_receipt;

        // recr_zero_price 抹零金额
        $positive_zero_price = isset($positive_price[$chun_id]->recr_zero_price) ? $positive_price[$chun_id]->recr_zero_price : 0;
        $minus_zero_price = isset($minus_price[$chun_id]->recr_zero_price) ? $minus_price[$chun_id]->recr_zero_price : 0;
        $zero_price = $positive_zero_price - $minus_zero_price;

        // 当前的欠收金额 = 结算金额 - 已收金额 - 抹零金额
        $bad_crop_price = $settle_price - $yet_receipt - $zero_price;
        return $bad_crop_price;
    }
}
