<?php

namespace app\admin\controller;

//销售单退货工单
use app\admin\model\ActionLog;
use app\admin\model\ProcessOrder;
use think\Exception;
use think\facade\Db;
use think\facade\Validate;

class ReorderChild extends Base
{

    //退货工单创建
    public function add()
    {

        $param = $this->request->only(['returnCode', 'list', 'type'], 'post', 'trim');

        $val = Validate::rule([
            'returnCode|退货单编号' => 'require',
            'list|退货工单集合' => 'require|array|max:100',
            'type|工单退货类型' => 'require|number|in:1,2',
        ]);
        if ($val->check($param) == false) return json_show(1004, $val->getError());

        $saleReturn = Db::name('sale_return')
            ->field('id,orderCode,status,companyNo,companyName,customer_code,customer_name')
            ->where(['is_del' => 0, 'returnCode' => $param['returnCode']])
            ->findOrEmpty();
        if (empty($saleReturn)) return json_show(1004, '该退货单不存在');
        if ($saleReturn['status'] != 11) return json_show(1004, '退货单状态有误');

        $sale = Db::name('sale')
            ->field('id,sale_price,good_num,total_price')
            ->where(['is_del' => 0, 'orderCode' => $saleReturn['orderCode']])
            ->findOrEmpty();
        if (empty($sale)) return json_show(1004, '销售单不存在');

        if ($param['type'] == 2) {
            //所有发货工单
            $orderOutChild = Db::name('order_out_child')
                ->where(['is_del' => 0, 'outChildCode' => array_unique(array_column($param['list'], 'outChildCode'))])
                ->column('outCode,wsm_code,num,status', 'outChildCode');
        }


        $val_child = Validate::rule([
            'outChildCode|发货工单号' => 'requireIf:type,2',
            'return_num|退货数量' => 'require|number|gt:0|max:999999999999',
            'return_wsm_code|退货仓库编码' => 'require',

        ]);

        Db::startTrans();

        try {

            $date = date('Y-m-d H:i:s');

            $insert = [];
            $i = 0;
            foreach ($param['list'] as $value) {

                $value['type'] = $param['type'];

                if ($val_child->check($value) == false) throw new Exception($val_child->getError());

                $insert[] = [
                    'orderCode' => $saleReturn['orderCode'],
                    'returnCode' => $param['returnCode'],
                    'outCode' => $param['type'] == 2 ? $orderOutChild[$value['outChildCode']]['outCode'] : '',
                    'outChildCode' => $value['outChildCode'] ?? '',
                    'order_out_child_status' => $param['type'] == 2 ? $orderOutChild[$value['outChildCode']]['status'] : '',
                    'saleReturnChildCode' => substr(makeNo('KCC'), 0, -2) . str_pad($i++, 2, '0', STR_PAD_LEFT),
                    'type' => $param['type'],
                    'companyNo' => $saleReturn['companyNo'],
                    'companyName' => $saleReturn['companyName'],
                    'customer_code' => $saleReturn['customer_code'],
                    'customerName' => $saleReturn['customer_name'],
                    'num' => $sale['good_num'],
                    'sale_price' => $sale['sale_price'],
                    'total_price' => $sale['total_price'],
                    'addtime' => $date,
                    'updatetime' => $date,
                    'record' => '',
                    'send_wsm_code' => $param['type'] == 2 ? $orderOutChild[$value['outChildCode']]['wsm_code'] : '',
                    'send_num' => $param['type'] == 2 ? $orderOutChild[$value['outChildCode']]['num'] : '',
                    'return_num' => $value['return_num'],
                    'return_wsm_code' => $value['return_wsm_code'],
                    'good_receive_type' => 0,
                    'loss_num' => 0,
                    'remark' => '',
                    'status' => 1,
                    'is_del' => 0,
                    'apply_id' => $this->uid,
                    'apply_name' => $this->uname,
                ];
            }

            if ($insert) Db::name('sale_return_child')->insertAll($insert);

            Db::name('sale_return')
                ->where(['is_del' => 0, 'id' => $saleReturn['id'], 'status' => 11])
                ->update(['status' => 12, 'updatetime' => $date]);

            Db::commit();
            return json_show(0, '设置退货工单成功');
        } catch (Exception $exception) {
            Db::rollback();
            return json_show(1004, $exception->getMessage());
        }
    }

    //退货工单列表
    public function getList()
    {

        $param = $this->request->only(['page' => 1, 'size' => 10, 'returnCode' => '', 'status' => '', 'orderCode' => '', 'outCode' => '', 'outChildCode' => '', 'saleReturnChildCode' => ''], 'post', 'trim');

        $where = [['a.is_del', '=', 0]];
        if ($param['returnCode'] != '') $where[] = ['a.returnCode', 'like', '%' . $param['returnCode'] . '%'];
        if ($param['status'] !== '') $where[] = ['a.status', '=', $param['status']];
        if ($param['orderCode'] != '') $where[] = ['a.orderCode', 'like', '%' . $param['orderCode'] . '%'];
        if ($param['outCode'] != '') $where[] = ['a.outCode', 'like', '%' . $param['outCode'] . '%'];
        if ($param['outChildCode'] != '') $where[] = ['a.outChildCode', 'like', '%' . $param['outChildCode'] . '%'];
        if ($param['saleReturnChildCode'] != '') $where[] = ['a.saleReturnChildCode', 'like', '%' . $param['saleReturnChildCode'] . '%'];

        $count = Db::name('sale_return_child')
            ->alias('a')
            ->where($where)
            ->count('a.id');

        $list = Db::name('sale_return_child')
            ->alias('a')
            ->field('a.id,a.saleReturnChildCode,a.type,a.outChildCode,a.outCode,a.companyNo,a.companyName,a.customer_code,a.customerName,a.num,a.sale_price,a.total_price,a.status,a.addtime')
            ->where($where)
            ->order(['a.addtime' => 'desc', 'a.id' => 'desc'])
            ->page($param['page'], $param['size'])
            ->select()
            ->toArray();

        return json_show(0, '获取列表成功', ['count' => $count, 'list' => $list]);

    }

    //库管收货(退货工单)
    public function receive()
    {
        $param = $this->request->only(['id', 'good_receive_type', 'loss_num', 'remark' => '', 'record' => ''], 'post', 'trim');

        $val = Validate::rule([
            'id|ID' => 'require|number|gt:0',
            'good_receive_type|货物情况' => 'require|number|between:1,4',
            'loss_num|丢失数量' => 'require|number|gt:0',
            'remark|备注' => 'max:255'
        ]);

        if ($val->check($param)) return json_show(1004, $val->getError());

        $info = Db::name('sale_return_child')
            ->alias('a')
            ->field('a.id,a.num,a.status,a.returnCode,a.outChildCode,a.return_num,a.return_wsm_code,a.orderCode,a.outCode,b.good_code spuCode,c.status order_out_status,b.id saleid,d.num thnum')
            ->leftJoin('sale b', 'b.orderCode=a.orderCode')
            ->leftJoin('order_out_child c', 'c.outChildCode=a.outChildCode AND c.is_del=0')
            ->leftJoin('sale_return d', 'd.returnCode=a.returnCode')
            ->where(['a.is_del' => 0, 'a.id' => $param['id']])
            ->findOrEmpty();
        if (empty($info)) return json_show(1004, '该退货工单不存在');
        if ($info['status'] != 1) return json_show(1004, '该退货工单已收货');
        if ($param['loss_num'] > $info['num']) return json_show(1004, '丢失数量大于下单数量');

        Db::startTrans();

        try {

            $date = date('Y-m-d H:i:s');

            //维护退货工单
            Db::name('sale_return_child')
                ->where(['is_del' => 0, 'id' => $param['id'], 'status' => 1])
                ->update([
                    'status' => 2,
                    'updatetime' => $date,
                    'good_receive_type' => $param['good_receive_type'],
                    'loss_num' => $param['loss_num'],
                    'remark' => $param['remark'],
                    'record' => $param['record']
                ]);

            //检查所属销售单的退货工单是否全部完成退货
            $temp = Db::name('sale_return_child')
                ->field('id')
                ->where(['is_del' => 0, 'returnCode' => $info['returnCode'], 'status' => 1])
                ->findOrEmpty();
            if (empty($temp)) {
                Db::name('sale_return')
                    ->where(['is_del' => 0, 'returnCode' => $info['returnCode'], 'status' => 12])
                    ->update(['status' => 4, 'updatetime' => $date]);

                //维护销售单
                $order = Db::name('sale')->where(['is_del' => 0, 'id' => $info['saleid']])->findOrEmpty();
                //未发货数量要减去发货单上的发货数量
//                $out_send_num = Db::name('order_out')
//                    ->where(['is_del' => 0, 'orderCode' => $info['orderCode'], 'status' => [0, 1]])
//                    ->sum('send_num');

//                $order['wsend_num'] -= $out_send_num;

                $thnum = $info['thnum'];//退货总数量
//                if ($order['wsend_num'] < $thnum) throw new Exception("销售单未发货数量不足退货");

                //如果  发货  维护销售单的
                //else 未发货数量减,
                if ($info['order_out_status'] == 1) {
                    $order['wsend_num'] -= $thnum;
                    $order['send_num'] += $thnum;
                }


//                $lor = $order['status'];

                $order['status'] = $order['wsend_num'] == 0 ? 2 : ($order['send_num'] == 0 ? 0 : 1);
                $order['send_status'] = $order['wsend_num'] == 0 ? 3 : ($order['send_num'] == 0 ? 1 : 2);
                $order['th_num'] += $thnum;
                if ($order['th_num'] == $order['send_num'] && $order['wsend_num'] == 0) {
                    $order['status'] = 3;
                }
                $order['th_fee'] += round($thnum * $order['sale_price'], 2);
                $order['updatetime'] = $date;
                $uap = Db::name("sale")->save($order);
                if ($uap == false) throw new Exception('销售单订单更新失败');

//                ActionLog::logAdd(['id' => $this->uid, 'nickname' => $this->uname], [
//                    "order_code" => $order["orderCode"],//出库单号
//                    "status" => $lor,//这里的status是之前的值
//                    "action_remark" => '',//备注
//                    "action_type" => "status"//新建create,编辑edit,更改状态status
//                ], "XSQRD", $order['status'], $order);
//
//                ProcessOrder::AddProcess(['id' => $this->uid, 'nickname' => $this->uname], [
//                    "order_type" => 'XSQRD',
//                    "order_code" => $order["orderCode"],//出库单号
//                    "order_id" => $order["id"],
//                    "order_status" => $order['status'], "before_status" => $lor
//                ]);
            }

            //发货工单数量减少
            Db::name('order_out_child')
                ->where(['is_del' => 0, 'outChildCode' => $info['outChildCode']])
                ->dec('num', $info['return_num'])
                ->update(['updatetime' => $date]);

            //维护bn
            if ($info['order_out_status'] == 1) {
                //待发货,说明此时有库存,有bn号
                Db::name('child_bn')
                    ->where(['orderCode' => $info['orderCode'], 'outCode' => $info['outCode'], 'childCode' => $info['outChildCode']])
                    ->inc('num', $info['return_num'])
                    ->update(['updatetime' => $date]);
                Db::name('good_stock')
                    ->where(['is_del' => 0, 'spuCode' => $info['spuCode'], 'wsm_code' => $info['return_wsm_code']])
                    ->inc('usable_stock', $info['return_num'])
                    ->dec('wait_out_stock', $info['return_num'])
                    ->update(['updatetime' => $date]);
            }


            Db::commit();
            return json_show(0, '设置退货工单成功');

        } catch (Exception $exception) {
            Db::rollback();
            return json_show(1004, $exception->getMessage());
        }

    }

    //详情
    public function info()
    {
        $param = $this->request->only(['id'], 'post', 'trim');

        $val = Validate::rule(['id' => 'require|number|gt:0']);

        if ($val->check($param) == false) return json_show(1004, $val->getError());

        $info = Db::name('sale_return_child')
            ->where(['is_del' => 0, 'id' => $param['id']])
            ->findOrEmpty();

        return empty($info) ? json_show(1004, '该退货工单不存在') : json_show(0, '获取退货工单详情成功', $info);

    }

}