<?php

namespace app\admin\controller;

//发货工单(从属于发货单)
use app\admin\model\ActionLog;
use app\admin\model\DataGroup as DataGroupModel;
use app\admin\model\GoodStockInfo;
use app\admin\model\ProcessOrder;
use think\Exception;
use think\facade\Db;
use think\facade\Validate;

class OrderOutChild extends Base
{

    //分单时可用仓库列表
    public function getWsmList()
    {
        $outCode = $this->request->post('outCode', '', 'trim');

        if ($outCode == '') return json_show(1004, '发货单号不能为空');

        $out = Db::name('order_out')
            ->alias('a')
            ->field('a.id,a.outCode,a.send_status,b.good_code')
            ->leftJoin('sale b', 'b.orderCode=a.orderCode')
            ->where(['a.is_del' => 0, 'a.outCode' => $outCode])
            ->findOrEmpty();
        if (empty($out)) return json_show(1004, '该发货单不存在');
        if ($out['send_status'] != 0) return json_show(1004, '该发货单状态错误');

        $list = Db::name("good_stock")
            ->alias("a")
            ->leftJoin("warehouse_info b", "a.wsm_code=b.wsm_code")
            ->field("a.id,a.wsm_code,b.name wsm_name,b.companyNo,b.companyName,b.supplierNo,b.supplierName,b.contactor_name,a.usable_stock")
            ->where(["spuCode" => $out['good_code'], "a.is_del" => 0])
            ->order(['id' => 'asc'])
            ->select()
            ->toArray();

        return json_show(0, '获取列表成功', $list);
    }

    //发货工单列表
    public function list()
    {
        $param = $this->request->only([
            'page' => 1,
            'size' => 10,
            'start' => '',
            'end' => '',
            'orderCode' => '',
            'customer_code' => '',
            'status' => '',
            'outChildCode' => '',
            'companyNo' => '',
            'spuCode' => '',
            'good_name' => '',
            'outCode' => '',
            'order_source' => '',
            'wsm_code' => '',
            'supplierNo' => '',
            'skuCode' => '',
            'apply_id' => '',
            'apply_name' => '',
            'order_type' => '',
            'relaComNo' => '',
            'use_type' => '',
            'IsByMe' => '0',
            "cgdNo"=>""
        ], 'post', 'trim');

        $where = [['a.is_del', '=', 0]];
        if ($param['start'] != '') $where[] = ['a.addtime', '>=', $param['start']];
        if ($param['end'] != '') $where[] = ['a.addtime', '<', $param['end'] . ' 23:59:59'];
        if ($param['orderCode'] != '') $where[] = ['a.orderCode', 'like', '%' . $param['orderCode'] . '%'];
        if ($param['customer_code'] != '') $where[] = ['a.customer_code', 'like', '%' . $param['customer_code'] . '%'];
        if ($param['status'] !== '') $where[] = ['a.status', '=', $param['status']];
        if ($param['outChildCode'] != '') $where[] = ['a.outChildCode', 'like', '%' . $param['outChildCode'] . '%'];
        if ($param['companyNo'] != '') $where[] = ['a.companyNo', 'like', '%' . $param['companyNo'] . '%'];
        if ($param['spuCode'] != '') $where[] = ['a.spuCode', 'like', '%' . $param['spuCode'] . '%'];
        if ($param['outCode'] != '') $where[] = ['a.outCode', 'like', '%' . $param['outCode'] . '%'];
        if ($param['order_source'] != '') $where[] = ['a.order_source', '=', $param['order_source']];
        if ($param['wsm_code'] != '') $where[] = ['a.wsm_code', 'like', '%' . $param['wsm_code'] . '%'];
        if ($param['supplierNo'] != '') $where[] = ['a.supplierNo', 'like', '%' . $param['supplierNo'] . '%'];
        if ($param['good_name'] != '') $where[] = ['a.good_name', 'like', '%' . $param['good_name'] . '%'];
        if ($param['skuCode'] != '') $where[] = ['a.skuCode', 'like', '%' . $param['skuCode'] . '%'];
        if ($param['apply_id'] !== '') $where[] = ['a.apply_id', '=', $param['apply_id']];
        if ($param['apply_name'] != '') $where[] = ['a.apply_name', 'like', '%' . $param['apply_name'] . '%'];
        if ($param['order_type'] != '') $where[] = ['a.order_type', '=', $param['order_type']];
        if ($param['relaComNo'] != '') $where[] = ['a.companyNo', '=', $param['relaComNo']];
        if ($param['use_type'] !== '') $where[] = ['p.use_type', '=', $param['use_type']];
		if ($param['cgdNo'] !== '') $where[] = ['m.cgdNo', '=', $param['cgdNo']];
        $condition = '1=1';
        if($param['IsByMe']==1)$condition = '1=0';
        //只有level2的账号过滤数据权限
        if ($this->level == 2) {
            //库管只能看到库存品订单,供应商负责人只能看到非库存品订单
            //是否是仓库管理员
            $tmp = Db::name('warehouse_info')->field('id')->where(['is_del' => 0, 'contactor' => $this->uid])->findOrEmpty();

            //库管看到所有的库存品发货申请单
            if (!empty($tmp)) $condition .= " or (a.order_type=1 AND c.contactor=" . $this->uid.")";
            else {
            	if($param['IsByMe']==0){
	                 $role = $this->checkDataShare();
	                if (!empty($role[DataGroupModel::$type_全部])) {
	                    $condition .= " or (a.apply_id in (" . implode(',', $role[DataGroupModel::$type_全部]) . "))";
	                }
            	}

            }
            $person_supplier = Db::connect('mysql_sys')
                ->name('supplier')
                ->where(['is_del' => 0, 'personid' => $this->uid])
                ->column('code');
            if ($person_supplier) {
            	if($param['IsByMe']==1){
            		$suppe = checkHasAccountBySupplierNos($person_supplier);
            		$suppAcco =array_diff($person_supplier,array_keys($suppe));
		            $person_supplier= $suppAcco;
            	}
                $condition .= " or (a.order_type<>1 and a.supplierNo in ('" . implode('\',\'', $person_supplier) . "'))";
            }
        }
         if ($this->level == 3 && $param['IsByMe']==1) {

         	 //是否是仓库管理员
            $tmp = Db::name('warehouse_info')->field('id')->where(['is_del' => 0, 'contactor' => $this->uid])->findOrEmpty();
             //库管看到所有的库存品发货申请单
            if (!empty($tmp)) $condition .= " or (a.order_type=1 AND c.contactor=" . $this->uid.")";
             $condition .= " or (a.order_type <>1 )";

        }

        $count = Db::name('order_out_child')
            ->alias('a')
            ->leftJoin('warehouse_info c', 'c.wsm_code=a.wsm_code AND c.is_del=0')
            ->leftJoin('sale d', 'd.orderCode=a.orderCode AND d.is_del=0')
            ->leftJoin('platform p', 'p.id=d.platform_id AND p.is_del=0')
            ->leftJoin('order_send m', 'a.outCode=m.outCode')
            ->where($where)
            ->where($condition)
            ->count('a.id');

        $list = Db::name('order_out_child')
            ->alias('a')
            ->field('a.*,c.supplierNo wsm_supplierNo,c.supplierName wsm_supplierName,c.name wsm_name,c.contactor_name,p.use_type,m.cgdNo,d.remark')
            ->leftJoin('warehouse_info c', 'c.wsm_code=a.wsm_code AND c.is_del=0')
            ->leftJoin('sale d', 'd.orderCode=a.orderCode AND d.is_del=0')
            ->leftJoin('platform p', 'p.id=d.platform_id AND p.is_del=0')
            ->leftJoin('order_send m', 'a.outCode=m.outCode')
            ->order(['a.addtime' => 'desc', 'a.id' => 'desc'])
            ->page($param['page'], $param['size'])
            ->where($where)
            ->where($condition)
            ->select()
            ->toArray();

//        $all_apply_id = array_column($list, 'apply_id');
//        $company_name = get_company_name_by_uid($all_apply_id);

        //校验是否开通了供应商账号
        $supp_account = checkHasAccountBySupplierNos(array_unique(array_column($list, 'supplierNo')));

        $data = [];
        foreach ($list as $value) {
//            $value['company_name'] = $company_name[$value['apply_id']] ?? '';
            $value['has_account'] = (int)isset($supp_account[$value['supplierNo']]);
            $data[] = $value;
        }

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

    //导出
    public function export()
    {
        $param = $this->request->only([
            'start' => '',
            'end' => '',
            'orderCode' => '',
            'customer_code' => '',
            'status' => '',
            'outChildCode' => '',
            'companyNo' => '',
            'spuCode' => '',
            'outCode' => '',
            'order_source' => '',
            'wsm_code' => '',
            'supplierNo' => '',
            'skuCode' => '',
            'apply_id' => '',
            'apply_name' => '',
            'order_type' => '',
            'relaComNo' => '',
            'use_type' => '',
            'IsByMe' => '0',
            "cgdNo"=>'',
        ], 'post', 'trim');

        $where = [['a.is_del', '=', 0]];
        if ($param['start'] != '') $where[] = ['a.addtime', '>=', $param['start']];
        if ($param['end'] != '') $where[] = ['a.addtime', '<', $param['end'] . ' 23:59:59'];
        if ($param['orderCode'] != '') $where[] = ['a.orderCode', 'like', '%' . $param['orderCode'] . '%'];
        if ($param['customer_code'] != '') $where[] = ['a.customer_code', 'like', '%' . $param['customer_code'] . '%'];
        if ($param['status'] !== '') $where[] = ['a.status', '=', $param['status']];
        if ($param['outChildCode'] != '') $where[] = ['a.outChildCode', 'like', '%' . $param['outChildCode'] . '%'];
        if ($param['companyNo'] != '') $where[] = ['a.companyNo', 'like', '%' . $param['companyNo'] . '%'];
        if ($param['spuCode'] != '') $where[] = ['a.spuCode', 'like', '%' . $param['spuCode'] . '%'];
        if ($param['outCode'] != '') $where[] = ['a.outCode', 'like', '%' . $param['outCode'] . '%'];
        if ($param['order_source'] != '') $where[] = ['a.order_source', '=', $param['order_source']];
        if ($param['wsm_code'] != '') $where[] = ['a.wsm_code', 'like', '%' . $param['wsm_code'] . '%'];
        if ($param['supplierNo'] != '') $where[] = ['a.supplierNo', 'like', '%' . $param['supplierNo'] . '%'];
        if ($param['skuCode'] != '') $where[] = ['a.skuCode', 'like', '%' . $param['skuCode'] . '%'];
        if ($param['apply_id'] !== '') $where[] = ['a.apply_id', '=', $param['apply_id']];
        if ($param['apply_name'] != '') $where[] = ['a.apply_name', 'like', '%' . $param['apply_name'] . '%'];
        if ($param['order_type'] != '') $where[] = ['a.order_type', '=', $param['order_type']];
        if ($param['relaComNo'] != '') $where[] = ['a.companyNo', '=', $param['relaComNo']];
        if ($param['use_type'] !== '') $where[] = ['p.use_type', '=', $param['use_type']];
        if ($param['cgdNo'] !== '') $where[] = ['m.cgdNo', '=', $param['cgdNo']];
        $condition = '1=1';
        if($param['IsByMe']==1)$condition = '1=0';
        //只有level2的账号过滤数据权限
        if ($this->level == 2) {
            //库管只能看到库存品订单,供应商负责人只能看到非库存品订单
            //是否是仓库管理员
            $tmp = Db::name('warehouse_info')->field('id')->where(['is_del' => 0, 'contactor' => $this->uid])->findOrEmpty();

            //库管看到所有的库存品发货申请单
            if (!empty($tmp)) $condition .= " or (a.order_type=1 AND c.contactor=" . $this->uid.")";
            else {
            	if($param['IsByMe']==0){
	                 $role = $this->checkDataShare();
	                if (!empty($role[DataGroupModel::$type_全部])) {
	                    $condition .= " or (a.apply_id in (" . implode(',', $role[DataGroupModel::$type_全部]) . "))";
	                }
            	}

            }
            $person_supplier = Db::connect('mysql_sys')
                ->name('supplier')
                ->where(['is_del' => 0, 'personid' => $this->uid])
                ->column('code');
            if ($person_supplier) {
            	if($param['IsByMe']==1){
            		$suppe = checkHasAccountBySupplierNos($person_supplier);
            		$suppAcco =array_diff($person_supplier,array_keys($suppe));
		            $person_supplier= $suppAcco;
            	}
                $condition .= " or (a.order_type<>1 and a.supplierNo in ('" . implode('\',\'', $person_supplier) . "'))";
            }
        }
         if ($this->level == 3 && $param['IsByMe']==1) {

         	 //是否是仓库管理员
            $tmp = Db::name('warehouse_info')->field('id')->where(['is_del' => 0, 'contactor' => $this->uid])->findOrEmpty();
             //库管看到所有的库存品发货申请单
            if (!empty($tmp)) $condition .= " or (a.order_type=1 AND c.contactor=" . $this->uid.")";
            $condition .= " or (a.order_type <>1 )";

        }

        $list = Db::name('order_out_child')
            ->alias('a')
            ->field('a.outChildCode 发货工单号,
            a.outCode 发货单编号,
            a.orderCode 销售订单编号,
            "" 供应商端,
            case a.status when 1 then "待发货" when 2 then "发货完成" when 3 then "已收货" when 4 then "已全部退货" end "状态" ,
            case a.order_type when 1 then "备库" when 2 then "非库存" when 3 then "咨询商品" when 4 then "报备商品" end "商品类型",
            case a.order_source when 1 then "直接下单" when 2 then "咨询" when 3 then "项目" when 4 then "平台" when 5 then "有赞" when 6 then "售后补换货" when 7 then "报备转单" when 8 then "支付渠道" end "订单来源",
            a.num 总数量,a.wsm_code 仓库编号,
            c.name 仓库名称,a.spuCode 商品成本编码,
            a.skuCode 商品上线编码,a.good_name 商品名称,a.companyNo 业务公司编号,
            a.companyName 业务公司名称,a.customer_code 客户编号,
            a.customer_name 客户名称,a.supplierNo 供应商编号,
            a.supplierName 供应商名称,a.addtime 下单时间,
            a.apply_name 申请人,
            case p.use_type when 0 then "无" when 1 then "to B" when 2 then "to C" end 对接类型,
            a.post_name 物流公司,a.post_code 物流单号,a.post_fee 物流费用,
            e.addr 收货地址,e.addr_code,e.contactor 收货联系人,e.mobile 联系方式,m.cgdNo 采购单号,d.remark 备注')
            ->leftJoin('warehouse_info c', 'c.wsm_code=a.wsm_code AND c.is_del=0')
            ->leftJoin('order_addr e', 'a.addrid=e.id')
            ->leftJoin('order_send m', 'a.outCode=m.outCode')
            ->leftJoin('sale d', 'd.orderCode=a.orderCode AND d.is_del=0')
            ->leftJoin('platform p', 'p.id=d.platform_id AND p.is_del=0')
            ->order(['a.addtime' => 'desc', 'a.id' => 'desc'])
            ->where($where)
            ->where($condition)
            ->select()
            ->toArray();

        //校验是否开通了供应商账号
        $supp_account = checkHasAccountBySupplierNos(array_unique(array_column($list, '供应商编号')));

//        $all_apply_id = array_column($list, 'apply_id');
//        $company_name = get_company_name_by_uid($all_apply_id);

//        $data = [];
        foreach ($list as &$value) {
            $value['供应商端'] = isset($supp_account[$value['供应商编号']]) ? '已开通' : '未开通';
                $addinfo =$value['addr_code']!=''?json_decode($value['addr_code'],true)??$value['addr_code']: '' ;
                if(is_string($addinfo)&&$addinfo!=''){
                    $addinfo=["provice_code"=>'',"city_code"=>'',"area_code"=>''];
                    list($addinfo['provice_code'],$addinfo['city_code'],$addinfo['area_code']) = explode(",",$value['addr_code']);
                 }
//                $addr['addr_cn'] =GetAddr(json_encode($addinfo));
			$value['收货地址'] = GetAddr(json_encode($addinfo)).$value['收货地址'];unset($value['addr_code']);
        }

        if (empty($list)) $list[] = ['没有相关可导出的数据'];
        excelSave('发货工单' . date('YmdHis'), array_keys($list[0]), $list);
//        return json_show(0, '获取成功', $data);
    }

    //拆单
    public function add()
    {
        $param = $this->request->only(['outCode', 'list'], 'post', 'trim');

        $val = Validate::rule([
            'outCode|发货单号' => 'require',
            'list' => 'require|array|max:100',
        ]);

//        $list=[
//            ['wsm_code'=>'','num'=>100],
//            ['wsm_code'=>'','num'=>100],
//        ];

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

        $val_child = Validate::rule([
            'wsm_code|仓库编码' => 'require',
            'num|发货数量' => 'require|number|gt:0|elt:999999999999',
        ]);

        $info = Db::name('order_out')
            ->alias('a')
            ->field('a.*,b.supplierNo companyNo,b.supplierName companyName,b.customer_code,b.customerName,b.supNo supplierNo,b.supName supplierName,b.good_code,b.skuCode,b.good_name,b.order_source,b.good_num,b.wsend_num')
            ->leftJoin('sale b', 'b.orderCode=a.orderCode AND b.is_del=0')
            ->where(['a.is_del' => 0, 'a.outCode' => $param['outCode'], 'a.send_status' => 1])
            ->findOrEmpty();

        if (empty($info)) return json_show(1004, '该发货单不存在或状态有误');
        if ($info['wsend_num'] < $info['send_num']) return json_show(1004, "订单待发货数量不足");
        if ($info['wsend_num'] < array_sum(array_column($param['list'], 'num'))) return json_show(1004, "仓库总发货数与发货单待发货数不同");

        //所有仓库信息
        $wsm = Db::name('good_stock')
            ->where(['is_del' => 0, 'spuCode' => $info['good_code'], 'wsm_code' => array_column($param['list'], 'wsm_code')])
            ->column('id', 'wsm_code');

        Db::startTrans();
        try {

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

            $insert = [];

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

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

                //改变编码规则,将原编码后两位换成序列号
                //str_pad字符串填充
                $outChildCode = substr(makeNo('TCD'), 0, -2) . str_pad($i++, 2, '0', STR_PAD_LEFT);

                $insert[] = [
                    'outChildCode' => $outChildCode,
                    'orderCode' => $info['orderCode'],
                    'outCode' => $param['outCode'],
                    'companyNo' => $info['companyNo'],
                    'companyName' => $info['companyName'],
                    'customer_code' => $info['customer_code'],
                    'customer_name' => $info['customerName'],
                    'supplierNo' => $info['supplierNo'],
                    'supplierName' => $info['supplierName'],
                    'spuCode' => $info['good_code'],
                    'skuCode' => $info['skuCode'],
                    'good_name' => $info['good_name'],
                    'order_type' => $info['order_type'],
                    'order_source' => $info['order_source'],
                    'num' => $value['num'],
                    'wsm_code' => $value['wsm_code'],
                    'apply_id' => $info['apply_id'],
                    'apply_name' => $info['apply_name'],
                    'addrid' => $info['addrid'],
                    'status' => 1,
                    'is_del' => 0,
                    'addtime' => $date,
                    'updatetime' => $date,
                ];

                if (!isset($wsm[$value['wsm_code']])) throw new Exception($value['wsm_code'] . '该仓库不存在');

            }

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

            foreach ($insert as $item) {
                GoodStockInfo::ChildAddBn($item['outChildCode'], $wsm[$value['wsm_code']]);//维护bn号
            }

            Db::name('order_out')
                ->where(['id' => $info['id'], 'is_del' => 0, 'outCode' => $param['outCode'], 'send_status' => 1])
                ->update(['send_status' => 2, 'status' => 1]);

            Db::commit();
            return json_show(0, '分单完成');
        } catch (Exception $exception) {
            Db::rollback();
            return json_show(1004, '分单失败,' . $exception->getMessage() . '|' . $exception->getFile() . '|' . $exception->getLine());
        }

    }

    //详情
    public function info()
    {

        $outChildCode = $this->request->post('outChildCode', '', 'trim');
        if ($outChildCode == '') return json_show(1004, '发货工单号不能为空');

        $info = Db::name('order_out_child')
            ->alias('a')
            ->field('a.*,b.name wsm_name,b.contactor,b.contactor_name')
            ->leftJoin('warehouse_info b', 'b.wsm_code=a.wsm_code')
            ->where(['a.is_del' => 0, 'a.outChildCode' => $outChildCode])
            ->findOrEmpty();
        //校验是否开通了供应商账号
        $supp_account = checkHasAccountBySupplierNos([$info['supplierNo']]);
		$info['remark'] = Db::name("sale")->where(["orderCode"=>$info['orderCode']])->value("remark",'');
        $info['has_account'] = (int)isset($supp_account[$info['supplierNo']]);
        return json_show(0, '获取详情成功', $info);

    }

    //发货
    public function send()
    {

        if ($this->level == 1) return json_show(0, '管理员不能操作');

        $param = $this->request->post('list/a', '', 'trim');

        $temp = Db::name('order_out_child')
            ->field('id,outChildCode')
            ->where(['is_del' => 0, 'outChildCode' => array_column($param, 'outChildCode')])
            ->where('status', '<>', 1)
            ->findOrEmpty();
        if (!empty($temp)) return json_show(1004, $temp['outChildCode'] . '状态错误,不能发货');

        $child = Db::name('order_out_child')
            ->where(['is_del' => 0, 'status' => 1, 'outChildCode' => array_column($param, 'outChildCode')])
            ->column('id,orderCode,outCode,num,wsm_code,supplierNo,apply_id', 'outChildCode');

        //检查所有的发货单是否有正在进行的售后单
        $temp = Db::name('order_return')
            ->where(['is_del' => 0, 'outCode' => array_unique(array_column($child, 'outCode'))])
            ->whereNotIn('status', [5, 6, 8])
            ->field('id,outCode')
            ->findOrEmpty();
        if (!empty($temp)) return json_show(1004, $temp['outCode'] . '有正在进行中的售后单,无法发货');

        $order_out = Db::name('order_out')
            ->where(['is_del' => 0, 'outCode' => array_unique(array_column($child, 'outCode'))])
            ->column('id,send_num,send_status,0 already_send_num,post_name,post_code,post_fee,status,apply_id', 'outCode');

        $sale = Db::name('sale')
            ->where(['is_del' => 0, 'orderCode' => array_unique(array_column($child, 'orderCode'))])
            ->column('id,good_num,send_num,wsend_num,good_code,supNo,is_stock,order_source,cgderid,status', 'orderCode');

        $is_reurn = Db::name("sale_return")
            ->field('id,orderCode')
            ->where(['orderCode' => array_column($child, 'orderCode'), 'is_del' => 0])
            ->where("status", "in", [1, 2, 3, 7, 8, 9, 10, 11, 12])
            ->findOrEmpty();
        if (!empty($is_reurn)) return json_show(1004, $is_reurn['orderCode'] . "存在退货未处理完成");


        //判断供应商是否开通账号,若开通的话,则只能由供应商账号操作
//        if ($this->level != 3) {
//            $temp = checkHasAccountBySupplierNos(array_column($sale, 'supNo'));
//            if (!empty($temp)) return json_show(1004, implode(',', array_keys($temp)) . '这些供应商已经开通账号,请使用供应商账号操作');
//        }


        $val = Validate::rule([
            'outChildCode|发货工单号' => 'require|max:255',
            'post_name|物流公司' => 'require|max:255',
            'post_code|物流单号' => 'require|alphaDash|max:255',
            'post_fee|物流费用' => 'require|egt:0|max:99999999.99'
        ]);

        Db::startTrans();
        try {

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

            //所有供应商负责人
            $person = get_personid_by_supplierNo(array_unique(array_column($child, 'supplierNo')));
//            $userCommon = \app\admin\common\User::getIns();
//            $person_temp = $userCommon->handle('sGetList', ['more_code' => array_unique(array_column($child, 'supplierNo')), 'size' => count(array_column($child, 'supplierNo'))]);
//            $person = array_column($person_temp['data']['list'], 'personid', 'code');
//            unset($userCommon);
//            unset($person_temp);

            //所有仓库管理员
            $wsm_contactor = Db::name('warehouse_info')
                ->where(['is_del' => 0, 'wsm_code' => array_unique(array_column($child, 'wsm_code'))])
                ->column('contactor', 'wsm_code');

            $yz_tmp = [];

            foreach ($param as $value) {

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

                //如果是库存品,只能由库管操作
                //其他商品,若level2只能由供应商负责人操作,level3不限制
                if ($sale[$child[$value['outChildCode']]['orderCode']]['is_stock'] == 1) {
                    if ($this->uid != $wsm_contactor[$child[$value['outChildCode']]['wsm_code']]) throw new Exception('库存品只能由仓库管理员操作');
                } else {
                    if (($this->level == 2) && ($this->uid != $person[$child[$value['outChildCode']]['supplierNo']])) throw new Exception('非库存品和采返商品只能由供应商负责人操作');
                }

//                if ($this->level == 2) {
//                    if ($sale[$child[$value['outChildCode']]['orderCode']]['is_stock'] == 1) {
//                        if ($this->uid != $wsm_contactor[$child[$value['outChildCode']]['wsm_code']]) throw new Exception('库存品只能由仓库管理员操作');
//                    } else {
//                        if ($this->uid != $person[$child[$value['outChildCode']]['supplierNo']]) throw new Exception('非库存品和采返商品只能由供应商负责人操作');
//                    }
//                }

//                if (($this->level) == 3 && ($sale[$child[$value['outChildCode']]['orderCode']]['is_stock'] == 1) && ($this->uid != $wsm_contactor[$child[$value['outChildCode']]['wsm_code']])) throw new Exception('库存品只能由仓库管理员操作');

                //工单
                if (!isset($child[$value['outChildCode']])) throw new Exception($value['outChildCode'] . '工单不存在或状态不允许发货');

                Db::name('order_out_child')
                    ->where(['id' => $child[$value['outChildCode']]['id'], 'is_del' => 0, 'status' => 1])
                    ->update([
                        'post_name' => $value['post_name'],
                        'post_code' => $value['post_code'],
                        'post_fee' => $value['post_fee'],
                        'status' => 2,
                        'sendtime' => $date,
                        'updatetime' => $date,
                    ]);

                //修改状态,添加待办
                ActionLog::logAdd(['id' => $this->uid, 'nickname' => $this->uname], [
                    "order_code" => $value['outChildCode'],//单号
                    "status" => 1,//这里的status是之前的值
                    "action_remark" => '',//备注
                    "action_type" => "status"//新建create,编辑edit,更改状态status
                ], "FHGD", 2, ['post_name' => $value['post_name'],
                    'post_code' => $value['post_code'],
                    'post_fee' => $value['post_fee'],
                    'status' => 2,
                    'sendtime' => $date,
                    'updatetime' => $date]);

                ProcessOrder::AddProcess(['id' => $this->uid, 'nickname' => $this->uname], [
                    "order_type" => 'FHGD',
                    "order_code" => $value['outChildCode'],//单号
                    "order_id" => $child[$value['outChildCode']]['id'],
                    "order_status" => 2,
                    "before_status" => 1,
                    'holder_id' => $child[$value['outChildCode']]['apply_id']
                ]);

                $order_out[$child[$value['outChildCode']]['outCode']]['already_send_num'] += $child[$value['outChildCode']]['num'];
                $order_out[$child[$value['outChildCode']]['outCode']]['already_send_num'] += $child[$value['outChildCode']]['num'];
                $order_out[$child[$value['outChildCode']]['outCode']]['already_send_num'] += $child[$value['outChildCode']]['num'];
				if($order_out[$child[$value['outChildCode']]['outCode']]['post_name']==''||$order_out[$child[$value['outChildCode']]['outCode']]['post_code']=='' ){
					$order_out[$child[$value['outChildCode']]['outCode']]['post_name']=  $value['post_name'];
					$order_out[$child[$value['outChildCode']]['outCode']]['post_code']=  $value['post_code'];
					$order_out[$child[$value['outChildCode']]['outCode']]['post_fee']=  $value['post_fee'];
				}
                //发货单
                //send_status 3部分发货,4全部发货
                Db::name('order_out')
                    ->where(['id' => $order_out[$child[$value['outChildCode']]['outCode']]['id']])
                    ->update([
                    	'send_status' => $order_out[$child[$value['outChildCode']]['outCode']]['already_send_num'] >= $order_out[$child[$value['outChildCode']]['outCode']]['send_num'] ? 4 : 3,
                    	'status' => 2,
                    	'post_name' => $order_out[$child[$value['outChildCode']]['outCode']]['post_name'],
                        'post_code' => $order_out[$child[$value['outChildCode']]['outCode']]['post_code'],
                        'post_fee' => $order_out[$child[$value['outChildCode']]['outCode']]['post_fee'],
                    	'updatetime' => $date,
                    	'sendtime' => $date
                    	 ]);

                $sale[$child[$value['outChildCode']]['orderCode']]['send_num'] += $child[$value['outChildCode']]['num'];
                $sale[$child[$value['outChildCode']]['orderCode']]['wsend_num'] -= $child[$value['outChildCode']]['num'];

                //修改状态,添加待办
                ActionLog::logAdd(['id' => $this->uid, 'nickname' => $this->uname], [
                    "order_code" => $child[$value['outChildCode']]['outCode'],//单号
                    "status" => $order_out[$child[$value['outChildCode']]['outCode']]['status'],//这里的status是之前的值
                    "action_remark" => '',//备注
                    "action_type" => "status"//新建create,编辑edit,更改状态status
                ], "CKD", 2, ['send_status' => $order_out[$child[$value['outChildCode']]['outCode']]['already_send_num'] >= $order_out[$child[$value['outChildCode']]['outCode']]['send_num'] ? 4 : 3, 'status' => 2, 'updatetime' => $date]);

                ProcessOrder::AddProcess(['id' => $this->uid, 'nickname' => $this->uname], [
                    "order_type" => 'CKD',
                    "order_code" => $child[$value['outChildCode']]['outCode'],//单号
                    "order_id" => $order_out[$child[$value['outChildCode']]['outCode']]['id'],
                    "order_status" => 2,
                    "before_status" => $order_out[$child[$value['outChildCode']]['outCode']]['status'],
                    'holder_id' => $order_out[$child[$value['outChildCode']]['outCode']]['apply_id']
                ]);


                //销售单
                $send_status = $sale[$child[$value['outChildCode']]['orderCode']]['send_num'] >= $sale[$child[$value['outChildCode']]['orderCode']]['good_num'] ? 3 :2;

                $sale_update_data = [
                    'send_num' => $sale[$child[$value['outChildCode']]['orderCode']]['send_num'],
                    'wsend_num' => $sale[$child[$value['outChildCode']]['orderCode']]['wsend_num'],
                    'send_status' => $send_status,
                    'updatetime' => $date
                ];

                if ($sale_update_data['wsend_num'] == 0) $sale_update_data['status'] = 2;
                elseif ($sale_update_data['send_num'] == 0) $sale_update_data['status'] = 0;
                else $sale_update_data['status'] = 1;

                Db::name('sale')
                    ->where(['is_del' => 0, 'id' => $sale[$child[$value['outChildCode']]['orderCode']]['id']])
                    ->update($sale_update_data);

                if ($sale[$child[$value['outChildCode']]['orderCode']]['order_source'] == 5 && $send_status == 3) {
                    $yz_tmp[] = [
                        'post_name' => $value['post_name'],
                        'post_code' => $value['post_code'],
                        'outCode' => $child[$value['outChildCode']]['outCode'],
                        'orderCode' => $child[$value['outChildCode']]['orderCode'],
                    ];
                }

                //修改状态,添加待办
                ActionLog::logAdd(['id' => $this->uid, 'nickname' => $this->uname], [
                    "order_code" => $child[$value['outChildCode']]['orderCode'],//单号
                    "status" => $sale[$child[$value['outChildCode']]['orderCode']]['status'],//这里的status是之前的值
                    "action_remark" => '',//备注
                    "action_type" => "status"//新建create,编辑edit,更改状态status
                ], "XSQRD", $sale_update_data['status'], $sale_update_data);

                ProcessOrder::AddProcess(['id' => $this->uid, 'nickname' => $this->uname], [
                    "order_type" => 'XSQRD',
                    "order_code" => $child[$value['outChildCode']]['orderCode'],//单号
                    "order_id" => $sale[$child[$value['outChildCode']]['orderCode']]['id'],
                    "order_status" => $sale_update_data['status'],
                    "before_status" => $sale[$child[$value['outChildCode']]['orderCode']]['status'],
                    'holder_id' => $sale[$child[$value['outChildCode']]['orderCode']]['cgderid']
                ]);

                //库存
                Db::name('good_stock')
                    ->data(['updatetime' => $date])
                    ->where(['is_del' => 0, 'spuCode' => $sale[$child[$value['outChildCode']]['orderCode']]['good_code'], 'wsm_code' => $child[$value['outChildCode']]['wsm_code']])
                    ->dec('wait_out_stock', $child[$value['outChildCode']]['num'])
                    ->update();

            }

            //日志、待办已办……

            Db::commit();


            //如果是有赞订单 且 所属发货单全部发货了,将发货信息推到有赞
            //有赞信息有可能推送失败(比如超过72小时,不允许多次修改等),所以不应该和这里的事务放到一起

            foreach ($yz_tmp as $temp) {
                curl_request(config('app.yz_domain') . 'api/yz_out_send', ['orderCode' => $temp['orderCode'], 'out_stype' => $temp['post_name'], 'post_code' => $temp['post_code'], 'uid' => $this->uid, 'uname' => $this->uname, 'order_out' => $temp['outCode']]);
            }
//            if ($einfo['order_source'] == 5) {
//                $res = curl_request(config('app.yz_domain') . 'api/yz_out_send', ['orderCode' => $einfo['orderCode'], 'out_stype' => $post_name, 'post_code' => $post_code, 'uid' => $uid, 'uname' => $uname, 'order_out' => $outCode]);
//                $res = json_decode($res, true);
//                if ($res['code'] != 0) return app_show(0, '发货成功,' . $res['message']);
//            }

            return json_show(0, '操作完成');

        } catch (Exception $exception) {

            Db::rollback();

            return json_show(1004, $exception->getMessage());
        }

    }

    //根据发货单号查询发货工单(不控制权限,不分页,无token,该方法加入白名单)
    public function getListByOutCode()
    {

        $param = $this->request->only(['outCode' => '', 'orderCode' => ''], 'post', 'trim');

        $val = Validate::rule([
            'outCode' => 'requireWithout:orderCode',
            'orderCode' => 'requireWithout:outCode',
        ]);

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

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

        $data = Db::name('order_out_child')
            ->alias('a')
            ->field('a.*,c.contactor_name,c.name wsm_name')
            ->leftJoin('warehouse_info c', 'c.wsm_code=a.wsm_code AND c.is_del=0')
            ->where($where)
            ->order(['a.addtime' => 'desc', 'a.id' => 'desc'])
            ->select()
            ->toArray();
        return json_show(0, '获取列表成功', $data);
    }

    //根据发货单号获取发货工单列表
    public function getList()
    {
        $param = $this->request->only(['outCode'], 'post', 'trim');

        $val = Validate::rule(['outCode' => 'require']);

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

        $where = ['a.is_del' => 0, 'outCode' => $param['outCode']];

        $list = Db::name('order_out_child')
            ->alias('a')
            ->field('a.*,c.supplierNo wsm_supplierNo,c.supplierName wsm_supplierName,c.name wsm_name,c.contactor_name')
            ->leftJoin('warehouse_info c', 'c.wsm_code=a.wsm_code AND c.is_del=0')
            ->order(['a.addtime' => 'desc', 'a.id' => 'desc'])
            ->where($where)
            ->select()
            ->toArray();

//        $all_apply_id = array_column($list, 'apply_id');
//        $company_name = get_company_name_by_uid($all_apply_id);

//        //校验是否开通了供应商账号
//        $supp_account = checkHasAccountBySupplierNos(array_unique(array_column($list, 'supplierNo')));
//
//        $data = [];
//        foreach ($list as $value) {
//            $value['company_name'] = $company_name[$value['apply_id']] ?? '';
//            $value['has_account'] = (int)isset($supp_account[$value['supplierNo']]);
//            $data[] = $value;
//        }

        return json_show(0, '获取成功', $list);
    }
    //退货旧数据生成发货工单
    public function  makeOutChild(){
    	    $param = $this->request->only(['outCode'], 'post', 'trim');
            $val = Validate::rule(['outCode' => 'require']);
            if($val->check($param)==false) return error_show(1004,$val->getError());
            $out=Db::name("order_out")->where(["outCode"=>$param['outCode'],"is_del"=>0])->findOrEmpty();
            if(empty($out))return error_show(1004,'发货单不存在');
            if(!in_array($out['status'],[2,3]))return error_show(1004,'发货单状态不满足条件');
			$sale=Db::name("sale")->where(["orderCode"=>$out['orderCode'],"is_del"=>0])->findOrEmpty();
			if(empty($sale))return error_show(1004,'订单不存在');
            if(!in_array($sale['status'],[1,2]))return error_show(1004,'订单状态不满足条件');
            $bninfo =Db::name("sale_info")->where([["orderCode","=",$out['orderCode']],["is_change_outbn","in",[1,2]]])
            ->select()->toArray();
            if(empty($bninfo)) return error_show(1004,'订单状态bn数据未找到');
            $isT= Db::name("order_out_child")->where(["outCode"=>$param['outCode'],"is_del"=>0])->findOrEmpty();
            if(!empty($isT))return error_show(1004,'发货单已存在工单');
            if($out['wsm_code']==''){
            	if($sale["order_type"]!=1) $cod =["b.supplierNo"=>$sale['supNo']];
            	else $cod =["b.companyNo"=>$sale['supplierNo']];
            	$wsmcode =Db::name("good_stock")->alias("a")
            	->leftJoin("warehouse_info b","a.wsm_code = b.wsm_code ")
            	->where("a.spuCode",$sale['good_code'])
            	->where("b.wsm_type","in",[2,5])
            	->where($cod)
            	->value("a.wsm_code",'');
            }else $wsmcode =$out['wsm_code'];
			$outchild=[
				"outChildCode"=>str_replace("DF","TCD",$param['outCode']),
				"orderCode"=>$out['orderCode'],
				"outCode"=>$out['outCode'],
				"companyNo"=>$sale['supplierNo'],
				"companyName"=>$sale['supplierName'],
				"customer_code"=>$sale['customer_code'],
				"customer_name"=>$sale['customerName'],
				"supplierNo"=>$sale['supNo'],
				"supplierName"=>$sale['supName'],
				"spuCode"=>$sale['good_code'],
				"skuCode"=>$sale['skuCode'],
				"good_name"=>$sale['good_name'],
				"order_type"=>$sale['order_type'],
				"order_source"=>$sale['order_source'],
				"num"=>$out['send_num'],
				"wsm_code"=>$wsmcode,
				"apply_id"=>$out['apply_id'],
				"apply_name"=>$out['apply_name'],
				"addrid"=>$out['addrid'],
				"post_name"=>$out['post_name'],
				"post_code"=>$out['post_code'],
				"post_fee"=>$out['post_fee'],
				"status"=>"2",
				"sendtime"=>$out['sendtime'],
				];

			$bnin=[];
			Db::startTrans();
			try{
				$sendnum =$out['send_num'];
				foreach ($bninfo as $item) {
					if($item['num']>=$sendnum){
						$temp=$sendnum;
						$item['num']-=$sendnum;
						$sendnum=0;
					}else{
						$temp= $item['num'];
						$sendnum-=$item['num'];
						$item['num']=0;
					}
			$bnin[]=[
				"childCode"=>$outchild['outChildCode'],
				"orderCode"=>$out['orderCode'],
				"outCode"=>$out['outCode'],
				"bnCode"=>$item['bnCode'],
				"num"=>$temp,
				"origin_price"=>$item['origin_price'],
				"total_bn_num"=>$temp
				];
				$up = Db::name("sale_info")->where(["id"=>$item['id']])
				->inc("change_num",$temp)
				->update(["is_change_outbn"=>$item['num']==0?3:2,"updatetime"=>date("Y-m-d H:i:s")]);
				if($up==false) throw new \Exception("订单bn更新失败");
				if($sendnum==0)break;
			}
			$makeChild =Db::name("order_out_child")->insert($outchild);
			if($makeChild==false) throw new \Exception("发货工单生成失败");
			$makeBn=Db::name("child_bn")->insertAll($bnin);
			if($makeBn==false) throw new \Exception("发货工单bn生成失败");
			$up = Db::name("order_out")->where(["outCode"=>$param['outCode'],"is_del"=>0])->update(["send_status"=>4]);
			if($up==false) throw new \Exception("发货单更新失败");
			Db::commit();
			return app_show(0,"发货工单生成完毕");
			}catch (\Exception $e){
				Db::rollback();
				return  error_show(1004,$e->getMessage());
			}

    }
}