<?php
/**
 * 销售出库管理Model
 * Created by PhpStorm.
 * User: 小威
 * Date: 2019/11/11
 * Time: 14:00
 */

namespace JinDouYun\Model\Stock;

use Exception;

use JinDouYun\Dao\Goods\DGoods;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\StatusCode;
use Mall\Framework\Core\ResultWrapper;

use JinDouYun\Cache\Stock;
use JinDouYun\Cache\OverviewCache;

use JinDouYun\Model\MBaseModel;
use JinDouYun\Model\Order\MOrder;
use JinDouYun\Model\Common\MCommon;
use JinDouYun\Model\Purchase\MPurchaseOut;
use JinDouYun\Model\System\MPrintNum;
use JinDouYun\Controller\Common\Logger;
use JinDouYun\Dao\Order\DOrder;
use JinDouYun\Dao\Order\DOrderIndex;
use JinDouYun\Model\Goods\MGoods;
use JinDouYun\Model\Order\MOrderGoods;
use JinDouYun\Model\Shop\MShop;
use JinDouYun\Model\System\MProcessSetting;
use JinDouYun\Model\Finance\MRefund;
use JinDouYun\Model\Finance\MAccount;
use JinDouYun\Model\System\MSystemPushMessage;
use JinDouYun\Model\System\MDriver;

use JinDouYun\Dao\Purchase\DPurchase;
use JinDouYun\Dao\Stock\DInventoryOut;
use JinDouYun\Dao\Stock\DInventoryOutDetails;
use JinDouYun\Dao\Customer\DCustomer;
use JinDouYun\Dao\GoodsManage\DGoodsBasic;
use Jindouyun\Dao\GoodsManage\DSku;

class MInventoryOut extends MBaseModel
{

    private $objDInventoryOut;
    private $objDInventoryOutDetails;
    private $enterpriseId;
    private $userCenterId;
    /**
     * @var int 单表数据量
     */
    private $cutTable = 200000;

    /**
     * @var Stock
     */
    private $objStockCache;

    /**
     * MInventoryOut constructor.
     * @param $enterpriseId
     * @param $userCenterId
     * @throws Exception
     */
    public function __construct($enterpriseId, $userCenterId)
    {
        $this->userCenterId = $userCenterId;
        $this->enterpriseId = $enterpriseId;
        parent::__construct($enterpriseId, $userCenterId);
        $this->objDInventoryOut = new DInventoryOut('stock');
        $this->objDInventoryOutDetails = new DInventoryOutDetails('stock');
        $this->objDInventoryOut->setTable($this->objDInventoryOut->get_Table() . '_' . $enterpriseId);
        $this->objDInventoryOutDetails->setTable($this->objDInventoryOutDetails->get_Table() . '_' . $enterpriseId);

        //$this->objDInventoryOut->setSearchIndex('inventory_out_search')->setType('inventory_out');
        $this->objStockCache = new Stock($this->enterpriseId);
    }

    /**
     * Doc: (des="获取订单出库单数量")
     * User: XMing
     * Date: 2021/2/23
     * Time: 10:41 上午
     * @param int $orderId
     * @return ResultWrapper
     */
    public function getTotalByOrderId(int $orderId): ResultWrapper
    {
        $where = [
            'sourceId' => $orderId,
            'source' => StatusCode::$orderType['saleOrder'],
            'deleteStatus' => StatusCode::$standard
        ];
        $total = $this->objDInventoryOut->count($where);
        if ($total === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(),ErrorCode::$dberror);
        }
        return ResultWrapper::success($total);
    }

    /**
     * 出库添加
     * @param $InventoryOutAddData
     * @return ResultWrapper
     * @throws Exception
     */
    public function addInventoryOut($InventoryOutAddData)
    {
        //接收参数
        //拿出详情数组
        $InventoryOutDetailsAddData = $InventoryOutAddData['orderGoodsData'];
        unset($InventoryOutAddData['orderGoodsData']);
        //定义固定参数
        $InventoryOutAddData['deleteStatus'] = StatusCode::$standard;
        $InventoryOutAddData['auditStatus'] = StatusCode::$auditStatus['auditing'];
        $InventoryOutAddData['outStatus'] = 1;
        $InventoryOutAddData['auditId'] = null;
        $InventoryOutAddData['auditName'] = null;
        $InventoryOutAddData['auditTime'] = null;
        $InventoryOutAddData['createTime'] = time();
        $InventoryOutAddData['updateTime'] = time();
        $InventoryOutAddData['deliveryType'] = isset($InventoryOutAddData['deliveryType']) ? $InventoryOutAddData['deliveryType'] : StatusCode::$deliveryType['logistics'];
        //no编号
        $dbResult =  $this->objDInventoryOut->get('createTime >='.strtotime(date('Ymd'.'0:0:0')), 'no', 'createTime desc');
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            $InventoryOutAddData['no'] = createSerialNumberByDate('');
        }else{
            $InventoryOutAddData['no'] = createSerialNumberByDate($dbResult['no']);
        }
        //$InventoryOutAddData['no'] = createOrderSn(StatusCode::$source['manage'], $InventoryOutAddData['type'], $this->enterpriseId);
        $InventoryOutAddData['serialNum'] = $this->objStockCache->createSerialSn();
        //开启事务
        $beginStatus = $this->objDInventoryOut->beginTransaction();
        //插入基础表
        $dbResult = $this->objDInventoryOut->insert($InventoryOutAddData);
        if ($dbResult === false) {
            $this->objStockCache->createSerialSn(1);
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        $InventoryOutId = $dbResult;

        //查询货架编码
        $params['details'] = $InventoryOutDetailsAddData;
        $modelResult = self::formatOutDetails($params);
        if(!$modelResult->isSuccess()){
            return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
        }
        $returnData = $modelResult->getData();
        unset($modelResult);
        $InventoryOutDetailsAddData = $returnData['details'];

        //定义固定参数
        foreach ($InventoryOutDetailsAddData as &$v) {
            $v['createTime'] = time();
            $v['updateTime'] = time();
            $v['linkId'] = $InventoryOutId;
            $v['linkNo'] = $InventoryOutAddData['no'];
        }
        unset($dbResult);
        //插入详情表
        $dbResult = $this->objDInventoryOutDetails->insert($InventoryOutDetailsAddData, true);
        if ($dbResult === false) {
            $this->objStockCache->createSerialSn(1);
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }

        //增加es搜索
        /*
        $modelResult = self::updateEsData($InventoryOutAddData, $InventoryOutId);
        if (!$modelResult->isSuccess()) {
            $this->objStockCache->createSerialSn(1);
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
        }*/

        //删除redis
        $objCacheStock = new Stock($this->enterpriseId);
        $cacheResult = $objCacheStock->deleteCacheStatistics('InventoryOut');
        if (!$cacheResult && $cacheResult !== 0) {
            $this->objStockCache->createSerialSn(1);
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail('删除缓存失败', ErrorCode::$paramError);
        }

        if(!empty($InventoryOutAddData['shopId'])){
            //删除未出库统计redis
            $objOverviewCache = new OverviewCache();
            $objOverviewCache->delStatisticsCountInventoryOut($this->enterpriseId, $InventoryOutAddData['shopId']);
        }

        $beginStatus && $this->objDInventoryOut->commit();
        return ResultWrapper::success($InventoryOutId);
    }

    /**
     * 删除出库单
     * @param $where
     * @return ResultWrapper
     * @throws Exception
     */
    public function delInventoryOutStatus($where)
    {
        $update = [
            'deleteStatus' => StatusCode::$delete,
            'updateTime' => time(),
        ];
        $dbResult = $this->objDInventoryOut->get($where);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        $inventoryOut = $dbResult;
        unset($dbResult);
        if(empty($inventoryOut)){
            return ResultWrapper::fail('出库单不存在', ErrorCode::$dberror);
        }
        $dbResult = $this->objDInventoryOut->update($update, $where);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }

        /*
        $modelResult = self::updateEs($update,$inventoryOut['id']);
        if(!$modelResult->isSuccess()){
            return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
        }
        unset($modelResult); */

        //删除redis
        $objCacheStock = new Stock($this->enterpriseId);
        $cacheResult = $objCacheStock->deleteCacheStatistics('InventoryOut');
        if (!$cacheResult && $cacheResult !== 0) {
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail('删除缓存失败', ErrorCode::$paramError);
        }
        //删除未出库统计redis
        $objOverviewCache = new OverviewCache();
        $objOverviewCache->delStatisticsCountInventoryOut($this->enterpriseId, $inventoryOut['shopId']);
        return ResultWrapper::success($dbResult);
    }

    /**
     * 出库审核
     * @param $params
     * @return ResultWrapper
     * @throws Exception
     */
    public function updateInventoryOutStatus($params)
    {
        // 手动审核分配出库物料数据
        if(isset($params['autoAudit']) && $params['autoAudit'] == StatusCode::$delete){
            $saveOutInventoryParams['outWarehouseData'] = $params['outWarehouseData'];
            $saveOutInventoryParams['UnassignedSkuData'] = $params['UnassignedSkuData'];
        }else{
            // 查询出库详情 计算出库仓库
            $modelResult = self::getInventoryOutInfo(['id' => $params['id']]);
            if(!$modelResult->isSuccess()){
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $inventoryOutData = $modelResult->getData();

            //出库单包含抄码商品禁止自动审核
            $inventoryOutIsEq = StatusCode::$delete;
            foreach($inventoryOutData['details'] as $value){
                if($inventoryOutIsEq == StatusCode::$standard) break;
                if($value['isEq'] == StatusCode::$standard) $inventoryOutIsEq = StatusCode::$standard;
            }
            if($inventoryOutIsEq == StatusCode::$standard) return ResultWrapper::fail('抄码商品禁止自动审核', ErrorCode::$paramError);
            $saveOutInventoryParams['outWarehouseData'] = isset($inventoryOutData['outWarehouseData']) ? $inventoryOutData['outWarehouseData'] : [];
            $saveOutInventoryParams['UnassignedSkuData'] = isset($inventoryOutData['UnassignedSkuData']) ? $inventoryOutData['UnassignedSkuData'] : [];
        }
        unset($params['outWarehouseData'], $params['UnassignedSkuData'],$params['autoAudit']);

        $where['id'] = $params['id'];
        unset($params['id']);
        $params['updateTime'] = time();
        $params['auditTime'] = time();
        $params['auditStatus'] = StatusCode::$auditStatus['auditPass'];
        $updateExpress = [
            'deliveryNo' => isset($params['deliveryNo']) ? $params['deliveryNo'] : '',
            'expressName' => isset($params['expressName']) ? $params['expressName'] : '',
            'expressId' => isset($params['expressId']) ? $params['expressId'] : 0,
            'logisticsData' => isset($params['logisticsData']) ? $params['logisticsData'] : null,
        ];
        unset($params['logisticsData'],$params['deliveryNo'],$params['expressName'],$params['expressId']);


        // 获取出库单数据
        $InventoryOutData = $this->objDInventoryOut->get($where);
        if ($InventoryOutData === false) {
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }

        if (empty($InventoryOutData)) {
            return ResultWrapper::fail('要审核的出库单不存在!', ErrorCode::$contentNotExists);
        }

        if ($InventoryOutData['auditStatus'] == StatusCode::$auditStatus['auditPass']) {
            //return ResultWrapper::fail('出库单已经审核过了!', ErrorCode::$notAllowAccess);
        }

        $updateExpress['deliveryType'] = $InventoryOutData['deliveryType'];

        //销售出库  已取消订单  不能审核
        $objMOrder = new MOrder($this->userCenterId, $this->enterpriseId);
        $order = [];
        if ($InventoryOutData['type'] == StatusCode::$orderType['saleOut']) {
            $modelResult = $objMOrder->getOrderIndexData(['no' => $InventoryOutData['sourceNo']]);
            if(!$modelResult->isSuccess()){
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $order = $modelResult->getData();
            unset($modelResult);
            if(empty($order)){
                return ResultWrapper::fail('关联订单不存在', ErrorCode::$paramError);
            }
            if($order['orderStatus'] == StatusCode::$orderStatus['close']){
                return ResultWrapper::fail('关联订单已取消', ErrorCode::$paramError);
            }
        }

        $beginStatus = $this->objDInventoryOut->beginTransaction();
        $modelResult = self::saveOutInventory($saveOutInventoryParams, ['id' => $where['id']]);
        if(!$modelResult->isSuccess()){
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
        }

        //查询出库物料
        $InventoryOutDetailsResult = $this->objDInventoryOutDetails->select(['linkId' => $where['id'], 'linkNo' => $InventoryOutData['no']]);
        if ($InventoryOutDetailsResult === false) {
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($this->objDInventoryOutDetails->error(), ErrorCode::$dberror);
        }

        //组装出库单数据
        $InventoryOutDetailsData = [];
        $outWarehouseIds = [];
        $outInventoryMap = [];
        $inventoryOutMoney = 0;
        foreach($InventoryOutDetailsResult as $value){
            if(!empty($value['outWarehouse'])){
                $value['outWarehouse'] = json_decode($value['outWarehouse'], true);
                foreach($value['outWarehouse'] as $outWarehouse){
                    if(!in_array($outWarehouse['warehouseId'],$outWarehouseIds)){
                        $outWarehouseIds[] = $outWarehouse['warehouseId'];
                    }
                    if($outWarehouse['num'] <= 0){
                        $this->objDInventoryOut->rollBack();
                        return ResultWrapper::fail($value['materielName'].'出库数量不能小于等于0', ErrorCode::$paramError);
                    }
                    $value['num'] = $outWarehouse['num'];
//                    $value['otherNum'] = $outWarehouse['otherNum'];
                    $InventoryOutDetailsData[$outWarehouse['warehouseId']][] = $value;
                    if (!isset($outInventoryMap[$value['skuId']])){
                        $outInventoryMap[$value['skuId']] = 0;
                    }
                    $outInventoryMap[$value['skuId']] = bcadd($outInventoryMap[$value['skuId']],$outWarehouse['num'],2);

                    // 计算实际出库单出库总金额
                    $inventoryOutMoney = bcadd( $value['totalPrice'], $inventoryOutMoney,  2);
                }
            }
        }


        // 获取计算成本方式
        $objMWarehouse = new MWarehouse($this->enterpriseId);
        $modelResult = $objMWarehouse->selectWarehouse(['id' => $outWarehouseIds]);
        if(!$modelResult->isSuccess()){
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
        }
        $warehouseResult = $modelResult->getData();
        unset($modelResult);
        $warehouseData = [];
        foreach($warehouseResult as $value){
            $warehouseData[$value['id']] = $value;
        }

        // 修改出库单状态
//        $params['amount'] = $inventoryOutMoney;
        $dbResult = $this->objDInventoryOut->update($params, $where);
        if ($dbResult === false) {
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }

        $InventoryOutData = array_merge($InventoryOutData, $params);
        // 操作库存
        $objMInventory = new MInventory($this->enterpriseId, $this->userCenterId);
        foreach($InventoryOutDetailsData as $warehouseId => $value){
            $costType = isset($warehouseData[$warehouseId]) ? $warehouseData[$warehouseId]['costType'] : StatusCode::$costType['mwa'];
            $InventoryOutData['warehouseId'] = $warehouseId;
            $InventoryOutData['Details'] = $value;
            $result = $objMInventory->updateInventory($InventoryOutData, $costType);
            if (!$result->isSuccess()) {
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail($result->getData(), $result->getErrorCode());
            }
        }


        //采购退货
        if ($InventoryOutData['type'] == StatusCode::$orderType['purchaseReturnOut']) {
            //出库状态回写
            $objMPurchaseOut = new MPurchaseOut($this->userCenterId, $this->enterpriseId);
            $modelResult = $objMPurchaseOut->updatePurchaseOutData(['outStatus' => StatusCode::$standard, 'updateTime' => time()], ['no' => $InventoryOutData['sourceNo']]);
            if (!$modelResult->isSuccess()) {
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
        }

        // 销售出库
        if ($InventoryOutData['type'] == StatusCode::$orderType['saleOut']) {
            // 回写销售订单出库状态
            $modelResult = $objMOrder->updateOutStatus(['orderStatus' => StatusCode::$orderStatus['waitReceive'], 'outTime' => time(), 'outStatus' => StatusCode::$standard, 'updateTime' => time()], ['no' => $InventoryOutData['sourceNo']], $outInventoryMap);
            if (!$modelResult->isSuccess()) {
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            //修改发货信息
//            $updateExpressResult = $objMOrder->editOrderExpress($InventoryOutData['sourceNo'],$updateExpress);
//            if (!$updateExpressResult->isSuccess()){
//                $this->objDInventoryOut->rollBack();
//                return ResultWrapper::fail($updateExpressResult->getData(),$updateExpressResult->getErrorCode());
//            }
            $objDCustomer = new DCustomer('default');
            $objDCustomer->setTable('qianniao_customer_' . $this->enterpriseId);

            $customerData = $objDCustomer->get( $InventoryOutData['customerId'],'userCenterId,openId');
            if ($customerData === false) {
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail($objDCustomer->error(), ErrorCode::$dberror);
            }
            $userCenterId = getArrayItem($customerData, 'userCenterId', StatusCode::$noneUserCenter);

            // 推送生成应收异步任务
            $i = 1;
            do {
                $postData = [
                    'topicName' => 'MyJob',
                    'topicClass' => 'Jobs\Model\MTopic\Finance\MReceivable',
                    'topicMethon' => 'createReceivable',
                    'topicMethonParams' => [
                        'userCenterId' => $userCenterId,
                        'enterpriseId' => $this->enterpriseId,
                        'id' => $InventoryOutData['id'], // 下推成出库单id
                        'type' => StatusCode::$orderType['saleOut'],
                    ],
                ];

                $url = QIANNIAO_QUEUE . '/CAddJob/add';
                $result = request($url, $postData);
                $i++;
            } while ($result['httpcode'] != 200 && $i <= 3);
            self::runProcessNextFinish($order['id'], $order);
            //判断有没有设置配送司机信息
            // 格式化 extend
            if (!empty($InventoryOutData['extend'])){
                $InventoryOutData['extend'] = json_decode($InventoryOutData['extend'],true);
            }
            $logistics = $InventoryOutData['extend'];
            $truckTel =''; //司机电话
            $truckName =''; //司机车牌
            $driverName =''; //司机名称
            if(!empty($logistics)){
                foreach ($logistics as $key => $value){
                    $truckTel = $value['truckTel'];
                    $truckName = $value['truckName'];
                    $driverName = $value['driverName'];
                }
                if (isset($customerData['openId']) && !empty($customerData['openId'])) {
                    // 发送小程序订阅消息
                    $sendMessageData = [
                        'time1'             => ['value' => date('Y-m-d H:i:s',time())], // 发货时间
                        'character_string2' => ['value' => StatusCode::$noPrefix[1].'-'.$order['no']], // 订单编号
                        'thing3'            => ['value' => $driverName], // 司机
                        'phone_number4'     => ['value' => $truckTel], // 司机电话
                        'car_number5'       => ['value' => $truckName], // 车牌号
                    ];
                    $objMSystemPushMessage = new MSystemPushMessage($this->userCenterId, $this->enterpriseId);
                    $result = $objMSystemPushMessage->sendWeiXinPushMessage(8,$customerData['openId'],$sendMessageData, '/pagesT/order/orderDetail?id='.$order['id']);
                    if (!$result->isSuccess()) {
                        file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/deliverGoods.log', date('Y-m-d H:i:s') . 'bb' . var_export($result->getData(), true) . PHP_EOL, FILE_APPEND);
                    }
                }
            }else{
                if (isset($customerData['openId']) && !empty($customerData['openId'])) {
                    // 发送小程序订阅消息
                    $sendMessageData = [
                        'time3'             => ['value' => date('Y-m-d H:i:s',time())], // 发货时间
                        'character_string7' => ['value' => StatusCode::$noPrefix[1].'-'.$order['no']], // 订单编号
                        'amount11'          => ['value' => $InventoryOutData['amount']], // 订单金额
                        'date13'            => ['value' => date('Y-m-d H:i:s',$order['createTime'])], // 下单时间
                        'thing20'           => ['value' => date('Y-m-d H:i:s',time())], // 配送时间
                    ];
                    $objMSystemPushMessage = new MSystemPushMessage($this->userCenterId, $this->enterpriseId);
                    $result = $objMSystemPushMessage->sendWeiXinPushMessage(2,$customerData['openId'],$sendMessageData, '/pagesT/order/orderDetail?id='.$order['id']);
                    if (!$result->isSuccess()) {
                        file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/deliverGoods.log', date('Y-m-d H:i:s') . 'bb' . var_export($result->getData(), true) . PHP_EOL, FILE_APPEND);
                    }
                }
            }
        }
        // 采购退货出库
        if ($InventoryOutData['type'] == StatusCode::$orderType['purchaseReturnOut']) {

            // 查询采购订单数据
            $objDPurchase =  new DPurchase();
            $objDPurchase->setTable('qianniao_purchase_'.$this->enterpriseId);
            $purchaseData = $objDPurchase->get($InventoryOutData['originId']);
            if($purchaseData === false){
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail($objDPurchase->error(), ErrorCode::$dberror);
            }
            if(empty($purchaseData)){
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail('采购订单数据为空', ErrorCode::$contentNotExists);
            }

            // 推送生成应付异步任务
            $i = 1;
            do {
                $postData = [
                    'topicName'         => 'MyJob',
                    'topicClass'        => 'Jobs\Model\MTopic\Finance\MPayable',
                    'topicMethon'       => 'createPayable',
                    'topicMethonParams' => [
                        'userCenterId' => $this->userCenterId,
                        'enterpriseId' => $this->enterpriseId,
                        'id'           => $InventoryOutData['id'],
                        'type'         => StatusCode::$orderType['purchaseReturnOut'],
                    ],
                ];

                $url = QIANNIAO_QUEUE . '/CAddJob/add';
                $result = request($url, $postData);
                $i++;
            } while ($result['httpcode'] != 200 && $i <= 3);
        }

        //  调拨出库审核生成调拨入库单
        if ($InventoryOutData['source'] == StatusCode::$orderType['allocate']) {
            // 获取调拨单数据
            $objMAllocate = new MAllocate($this->enterpriseId, $this->userCenterId);
            $modelResult = $objMAllocate->getAllocate(['id' => $InventoryOutData['originId']]);
            if (!$modelResult->isSuccess()) {
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $allocateData = $modelResult->getData();
            unset($modelResult);
            if( empty($allocateData) ){
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail('id为'.$inventoryOutIsEq['originId'].' 的调拨单不存在', ErrorCode::$contentNotExists);
            }

            // 获取调拨入库仓库数据
            $modelResult = $objMWarehouse->getWarehouse(['id' => $allocateData['inWarehouseId']]);
            if(!$modelResult->isSuccess()){
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $inWarehouseData = $modelResult->getData();
            unset($modelResult);
            if (empty($inWarehouseData)) {
                $this->objDInventoryOut->rollBack();
                return ResultWrapper::fail('id为'.$inventoryOutIsEq['originId'].' 的调拨单入库仓库查询失败', ErrorCode::$paramError);
            }

            //增加入库
            $inventoryIn['sourceId'] = $InventoryOutData['id'];
            $inventoryIn['sourceNo'] = $InventoryOutData['no'];
            $inventoryIn['materielNum'] = 0;
            $inventoryIn['amount'] = 0;
            $inventoryIn['originId'] = $InventoryOutData['originId'];
            $inventoryIn['originNo'] = $InventoryOutData['originNo'];
            $inventoryIn['warehouseId'] = $allocateData['inWarehouseId'];
            $inventoryIn['warehouseName'] = $inWarehouseData['warehouseName'];
            $inventoryIn['operatorId'] = $InventoryOutData['auditId'];
            $inventoryIn['operatorName'] = $InventoryOutData['auditName'];
            $inventoryIn['remark'] = $InventoryOutData['remark'];
            $inventoryIn['source'] = StatusCode::$orderType['allocateOut'];
            $inventoryIn['type'] = StatusCode::$orderType['allocateIn'];
            $inventoryIn['details'] = [];
            foreach ($InventoryOutDetailsData as $item) {
                foreach($item as $value){
                    $inventoryIn['materielNum']++;
                    $inventoryIn['amount'] += bcmul($value['num'], $value['unitPrice'], 4);
                    $inDetails['materielId'] = $value['materielId'];
                    $inDetails['materielName'] = $value['materielName'];
                    $inDetails['materielCode'] = $value['materielCode'];
                    $inDetails['skuId'] = $value['skuId'];
                    $inDetails['unitName'] = $value['unitName'];
                    $inDetails['skuName'] = $value['skuName'];
                    $inDetails['num'] = $value['num'];
                    $inDetails['otherNum'] = $value['otherNum'];
                    $inDetails['unitPrice'] = $value['unitPrice'];
                    $inventoryIn['orderGoodsData'][] = $inDetails;
                }
            }
            $objMInventoryIn = new MInventoryIn($this->enterpriseId, $this->userCenterId);
            $modelResult = $objMInventoryIn->addInventoryIn($inventoryIn);
            if (!$modelResult->isSuccess()) {
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            unset($modelResult);
        }

        //修改es
        /*
        $esId = self::esId($InventoryOutData['id']);
        $esResult = $this->objDInventoryOut->esupdateTypeFieldVaule($params, $esId);
        if(!$esResult){
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail($esResult, ErrorCode::$paramError);
        }
        unset($esResult);*/

        //删除redis
        $objCacheStock = new Stock($this->enterpriseId);
        $cacheResult = $objCacheStock->deleteCacheStatistics('InventoryOut');
        if (!$cacheResult && $cacheResult !== 0) {
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail('删除缓存失败', ErrorCode::$paramError);
        }

        //删除未出库统计redis
        $objOverviewCache = new OverviewCache();

        $objOverviewCache->delStatisticsCountInventoryOut($this->enterpriseId, $InventoryOutData['shopId']);

        $beginStatus && $this->objDInventoryOut->commit();
        return ResultWrapper::success($dbResult);
    }

    /**
     * 出库单分配仓库
     * @param $params
     * @param $where
     * @return ResultWrapper
     */
    public function saveOutInventory($params, $where)
    {
        $outInventoryId = $where['id'];
        //查询详情数据
        $dbResult = $this->objDInventoryOutDetails->select(['linkId' => $outInventoryId]);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOutDetails->error(), ErrorCode::$dberror);
        }
        $outInventoryDetailsResult = $dbResult;
        unset($dbResult);
        //格式化详情数据
        $outInventoryDetailsData = [];
        foreach($outInventoryDetailsResult as $value){
            $outInventoryDetailsData[$value['skuId']] = $value;
        }

        //格式化未分配出库数据
        $UnassignedSkuData = [];
        if(!empty($params['UnassignedSkuData'])){
            foreach($params['UnassignedSkuData'] as $value){
                $UnassignedSkuData[$value['skuId']] = $value;
            }
        }
        //循环出库仓库数据
        $skuOutNumTotal = [];
        foreach($params['outWarehouseData'] as $value){
            $warehouseId = $value['warehouseId'];
            foreach($value['details'] as $skuData){
                if(!isset($skuOutNumTotal[$skuData['skuId']])){
                    $skuOutNumTotal[$skuData['skuId']] = [
                        'num' => 0,
                        'otherNum'=>$skuData['otherNum'],
                        'areaId' => $skuData['areaId'],
                        'areaName' => $skuData['areaName'],
                        'areaCode' => $skuData['areaCode'],
                        'storageLocationId' => $skuData['storageLocationId'],
                        'storageLocationName' => $skuData['storageLocationName'],
                        'storageLocationCode' => $skuData['storageLocationCode'],
                        'outWarehouse' => [],
                        'materielName' => $skuData['materielName']
                    ];
                }
                $skuOutNumTotal[$skuData['skuId']]['num'] = isset($skuOutNumTotal[$skuData['skuId']]) ? bcadd($skuOutNumTotal[$skuData['skuId']]['num'], $skuData['num'],8) : $skuData['num'];
                $skuOutNumTotal[$skuData['skuId']]['outWarehouse'][] = [
                    'warehouseId' => $warehouseId,
                    'num' => $skuData['num'],
                    'otherNum' => $skuData['otherNum'],
                ];
            }
        }
        $updates = [];
        foreach($skuOutNumTotal as $skuId => $value){
            //出库数量
            $outNum = $value['num'];
            //未出库数量
            $outUnassignedNum = isset($UnassignedSkuData[$skuId]) ? $UnassignedSkuData[$skuId]['num'] : 0;
            //总数量
            $taotal = isset($outInventoryDetailsData[$skuId]) ? $outInventoryDetailsData[$skuId]['total'] : 0;
            if(bccomp(bcadd($outNum,$outUnassignedNum,8),$taotal) != 0){
                return ResultWrapper::fail($value['materielName'].'出库数量错误', ErrorCode::$paramError);
            }
            $update = [
                'outWarehouse' => json_encode($value['outWarehouse']),
                'num' => $outUnassignedNum,
                'otherNum'=>$value['otherNum'],
                'areaId' => $value['areaId'],
                'areaName' => $value['areaName'],
                'areaCode' => $value['areaCode'],
                'storageLocationId' => $value['storageLocationId'],
                'storageLocationName' => $value['storageLocationName'],
                'storageLocationCode' => $value['storageLocationCode'],
                'outNum' => $outNum,
                'updateTime' => time(),
            ];
            $dbResult = $this->objDInventoryOutDetails->update($update, ['linkId' => $outInventoryId, 'skuId' => $skuId]);
            if($dbResult === false){
                return ResultWrapper::fail($this->objDInventoryOutDetails->error(), ErrorCode::$dberror);
            }
            $updates[$skuId] = $update;
        }
        return ResultWrapper::success($updates);
    }

    /**
     * 查询一个单据所有出库物料出库数量
     */
    public function getInventoryOutByOriginId($originId, $source)
    {
        $where = [
            'originId' => $originId,
            'source' => $source,
            'deleteStatus' => StatusCode::$standard,
            'auditStatus' => StatusCode::$auditStatus['auditPass']
        ];
        $dbResult = $this->objDInventoryOut->select($where);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        $inventoryOut = $dbResult;
        unset($dbResult);
        if(empty($inventoryOut)){
            return ResultWrapper::fail('出库单据不存在', ErrorCode::$paramError);
        }
        $inventoryOutIds = array_column($inventoryOut, 'id');
        $dbResult = $this->objDInventoryOutDetails->select(['linkId' => $inventoryOutIds]);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOutDetails->error(), ErrorCode::$dberror);
        }
        $details = [];
        foreach($dbResult as $value){
            if(!isset($details[$value['skuId']])){
                $details[$value['skuId']] = [
                    'outWarehouse' => json_decode($value['outWarehouse'], true),
                    'materielId' => $value['materielId'],
                    'materielName' => $value['materielName'],
                    'materielCode' => $value['materielCode'],
                    'skuId' => $value['skuId'],
                    'unitName' => $value['unitName'],
                    'skuName' => $value['skuName'],
                    'skuStorage' => $value['skuStorage'],
                    'num' => $value['outNum'],
                    'total' => $value['total'],
                    'outStatus' => $value['outStatus'],
                ];
            }else{
                $details[$value['skuId']]['outWarehouse'] = array_merge($details[$value['skuId']]['outWarehouse'], json_decode($value['outWarehouse'], true));
                $details[$value['skuId']]['num'] = bcadd($details[$value['skuId']]['num'], $value['outNum'], 8);
            }
        }
        return ResultWrapper::success($details);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/11/9
     * Time: 9:57 上午
     * @param int $orderId
     * @param array $order
     * @return ResultWrapper
     * @throws Exception
     */
    private function runProcessNextFinish(int $orderId,array $order): ResultWrapper
    {
        if (empty($orderId)){
            return ResultWrapper::success(true);
        }
        if ($order['orderType'] != StatusCode::$orderType['saleOrder']){
            return ResultWrapper::success(true);
        }
        $objMProcessSetting = new MProcessSetting($this->enterpriseId);
        $setResult = $objMProcessSetting->getProcessSettingByType(StatusCode::$processType['sales'],'finish');
        if (!$setResult->isSuccess()){
            Logger::logs(E_USER_ERROR,'获取流程配置出错',__CLASS__,__LINE__,$setResult->getData());
            return ResultWrapper::fail($setResult->getData(),$setResult->getErrorCode());
        }
        $set = $setResult->getData();
        if (empty($set)){
            Logger::logs(E_USER_ERROR,'配置为空',__CLASS__,__LINE__,'');
            return ResultWrapper::success(true);
        }
        if (isset($set['enableStatus']) && $set['enableStatus'] == StatusCode::$standard){
            Logger::logs(E_USER_ERROR,'配置',__CLASS__,__LINE__,$set);
            return ResultWrapper::success(true);
        }
        $objMOrder = new MOrder($this->userCenterId, $this->enterpriseId);
        $params = [
            'orderStatus' => StatusCode::$orderStatus['finish']
        ];
        $result = $objMOrder->updateOrderStatus($orderId,$params,[]);
        if (!$result->isSuccess()){
            Logger::logs(E_USER_ERROR,'自动完成订单失败',__CLASS__,__LINE__,$result->getData());
            return ResultWrapper::fail($result->getData(),$result->getErrorCode());
        }
        Logger::logs(E_USER_ERROR,'自动完成订单成功',__CLASS__,__LINE__,$orderId);
        return ResultWrapper::success(true);
    }

    /**
     * 出库列表
     * @param $selectParams
     * @return ResultWrapper
     * @throws Exception
     */
    public function getAllInventoryOut($selectParams,$export=0)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);

        $selectParams['deleteStatus'] = StatusCode::$standard;
        if (isset($selectParams['type'])){
            $type = $selectParams['type'];
        }

       
        $selectParams = self::formatSqlWhere($selectParams);
        // 映射仓库名称
        $objMAllocate = new MAllocate($this->enterpriseId,$this->userCenterId);
        if($export){
            $linkedTab =' qianniao_inventory_out_'.$this->enterpriseId.' as o left join  qianniao_inventory_out_details_'.$this->enterpriseId.' as d ON o.id=d.linkId ';
            $whereSql = '';
            if(isset($type) && !empty($type)){
                $whereSql = ' o.type= '.$type.' and ';
            }
            $where = $whereSql.'  o.deleteStatus='.StatusCode::$standard.' ORDER BY o.createTime desc';
            $sql ='select * from '.$linkedTab.' where '.$where;
            $exportDbResult = $this->objDInventoryOut->query($sql);
            if ($exportDbResult === false) {
                return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
            }
            $data = $objMAllocate->getAllocateInfoByWarehouseName($exportDbResult);
            if(!$data->isSuccess()){
                return ResultWrapper::fail($objMAllocate->error(), ErrorCode::$dberror);
            }
            $dbResult = $data->getData();
            $export = parent::formatOrderMan($this->enterpriseId, $dbResult);
            self::exportInventoryOut($export);
            exit;
        }
        $dbResult = $this->objDInventoryOut->select($selectParams, '*', 'createTime desc', $limit, $offset);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        
        $data = $objMAllocate->getAllocateInfoByWarehouseName($dbResult);
        if(!$data->isSuccess()){
            return ResultWrapper::fail($objMAllocate->error(), ErrorCode::$dberror);
        }
        $dbResult = $data->getData();
        $total = $this->objDInventoryOut->count($selectParams);
        $return = [
            'data'  => parent::formatOrderMan($this->enterpriseId, $dbResult),
            'total' => ($total) ? intval($total) : 0,
        ];

        if ($return === false) {
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        } else {
            return ResultWrapper::success($return);
        }
    }
    
    /**
     * 出库导出方法
     * @param $inventoryOutData
     */
    public function exportInventoryOut($inventoryOutData)
    {
        
        //导出到本地
        header("Content-type:application/vnd.ms-excel");
        header("Content-Disposition:filename=出库管理.csv");
        header('Cache-Control: max-age=0');
        
        $fp = fopen('php://output', 'a');
        
        $head = ['ID', '单据编号','制单时间','调出仓库', '客户', '客户电话','来源单号','配送方式', '出库类型', '审核人', '打印次数','商品名称','商品编码','规格','销售量','出库数量','销售单价','销售总金额','销售总金额（优惠后）','货架编码','商品条码'];       //定义标题
        
        foreach ($head as $i => $v) {
            $head[$i] = mb_convert_encoding($v, 'GBK', 'utf-8');     //将中文标题转换编码，否则乱码
        }
        
        fputcsv($fp, $head);
        
        $limit = 10000;
        $num = 0;//计数器
        foreach ($inventoryOutData as $value) {//循环数据
            $num++;
            if ($num == $limit) {
                ob_flush();//释放内存
                flush();
            }
            $rows['id'] = isset($value['linkId']) ? $value['linkId'] : null; // ID
            $rows['no'] = isset($value['no']) ? $value['no'] : null; // 单据编号
            $rows['createTime'] = isset($value['createTime']) ? date("Y-m-d H:i:s",$value['createTime']) : null; // 制单日期
            $rows['warehouseName'] = isset($value['warehouseName']) ? $value['warehouseName'] : null; // 调出仓库
            $rows['customerName'] = isset($value['customerName']) ? $value['customerName'] : null; // 客户
            $rows['customerMobile'] = isset($value['customerMobile']) ? $value['customerMobile'] : null; // 客户电话
            $rows['sourceNo'] = isset($value['sourceNo']) ? $value['sourceNo'] : null; // 来源单号
            $rows['deliveryName'] = isset($value['deliveryName']) ? $value['deliveryName'] : null; // 配送方式
            $rows['typeName'] = isset($value['typeName']) ? $value['typeName'] : null; // 出库类型
            $rows['auditName'] = isset($value['auditName']) ? $value['auditName'] : null; // 审核人
            $rows['printNum'] = isset($value['printNum']) ? $value['printNum'] : null; // 打印次数
            $rows['materielName'] = isset($value['materielName']) ? $value['materielName'] : null; // 商品名称
            $rows['materielCode'] = isset($value['materielCode']) ? $value['materielCode'] : null; // 商品编码
            $rows['specs'] = !empty($value['unitName']) && !empty($value['skuName']) ? $value['unitName'].';'.$value['skuName'] : $value['unitName']; // 规格
            $rows['total'] = isset($value['total']) ? $value['total'] : null; // 销售量
            $rows['outNum'] = isset($value['outNum']) ? $value['outNum'] : null; // 出库数量
            $rows['unitPrice'] = isset($value['unitPrice']) ? $value['unitPrice'] : null; // 销售单价
            $rows['originTotalPrice'] =  bcmul($value['unitPrice'], $value['num'],2); // 销售总金额
            $rows['totalPrice'] = isset($value['totalPrice']) ? $value['totalPrice'] : null; // 销售总金额（优惠后）
            $rows['skuStorage'] = isset($value['skuStorage']) ? $value['skuStorage'] : null; // 货架编码
            $rows['skuBarCode'] = isset($value['skuBarCode']) ? $value['skuBarCode'] : null; // 商品条码
            
            foreach ($rows as $kk => $vv) {
                $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8');  //转译编码
            }
            fputcsv($fp, $rs);
            $rows = [];
        }
    }
    /**
     * 出库列表搜索
     * @param $params
     * @return ResultWrapper
     * @throws Exception
     */
    public function searchAllInventoryOut($params)
    {
        $defaultDSL = ['from' => $params['offset'], 'size' => $params['limit'], 'sort' => ['createTime' => ['order' => 'desc']]];
        $selectParams = [];
        $selectParams[] = ['term' => ['deleteStatus' => StatusCode::$standard]];
        $selectParams[] = ['term' => ['enterpriseId' => $this->enterpriseId]];
        !empty($params['type']) && $selectParams[] = ['term' => ['type' => $params['type']]];
        !empty($params['shopId']) && $selectParams[] = ['term' => ['shopId' => $params['shopId']]];
        !empty($params['warehouseId']) && $selectParams[] = ['term' => ['warehouseId' => $params['warehouseId']]];
        !empty($params['auditStatus']) && $selectParams[] = ['terms' => ['auditStatus' => is_array($params['auditStatus']) ? $params['auditStatus'] : [$params['auditStatus']]]];
        (!empty($params['start']) && !empty($params['end'])) && $selectParams[] = ['range' => ['createTime' => ['gte' => $params['start'], 'lte' => $params['end']]]];
        !empty($params['search']) && $selectParams[] = ['multi_match' => ['fields' => ['no', 'sourceNo', 'operatorName', 'customerName', 'customerMobile'], 'query' => $params['search'], 'fuzziness' => 'AUTO']];
        $dsl = [];
        !empty($selectParams) && $dsl['query']['bool']['must'][] = $selectParams;
        $dsl = array_merge($defaultDSL, $dsl);
        $dbResult = $this->objDInventoryOut->getSearchQueryDsl($dsl);
        if (isset($dbResult['error'])) {
            if ($dbResult['error']['reason'] == 'no such index') {
                return ResultWrapper::success(['data' => [], 'total' => 0]);
            }
            return ResultWrapper::fail($dbResult, ErrorCode::$dberror);
        }
        $returnData = parent::formatEsSelectData($dbResult);
        $objMCommon = new MCommon();
        foreach($returnData['data'] as &$value){
            if (isset($value['deliveryType']) && !empty($value['deliveryType'])) $value['deliveryName'] = StatusCode::$deliveryType[$value['deliveryType']];
            $value['typeName'] = $objMCommon->formatOrderSource($value['type']);
        }
        unset($value);
        return ResultWrapper::success($returnData);
    }

    /**
     * 出库统计
     * @param $type
     * @return ResultWrapper
     * @throws Exception
     */
    public function statisticsAllInventoryOut($type, $shopId = 0)
    {
        if($shopId){
            $sql = "select `type`,count(id) as count from ".$this->objDInventoryOut->get_Table()." where deleteStatus = ".StatusCode::$standard." and shopId = ".$shopId." GROUP BY `type`";
            $dbResult = $this->objDInventoryOut->query($sql);
            if($dbResult === false){
                return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
            }
            $typeData = [];
            foreach($dbResult as $value){
                $typeData[$value['type']] = $value['count'];
            }
            $cacheData = [];
            foreach($type as $value){
                $cacheData[] = [
                    'type' => $value,
                    'count' => isset($typeData[$value]) ? $typeData[$value] : 0,
                ];
            }
            return ResultWrapper::success($cacheData);
        }
        $cacheKey = 'InventoryOut';
        $objCacheStock = new Stock($this->enterpriseId);
        $cacheData = [];
        //判断redis里有没有这个key
        $cacheResult = $objCacheStock->getCacheStatisticsCount($cacheKey);
        $issetCacheKey = $cacheResult;
        unset($cacheResult);
        foreach ($type as $value) {
            $cacheResult = $objCacheStock->getCacheStatistics($value, $cacheKey);
            $cacheData[] = [
                'type'  => $value,
                'count' => $cacheResult ? $cacheResult : 0,
            ];
            unset($cacheResult);
        }
        //如果有就拿出来  当做值返回
        if ($issetCacheKey) return ResultWrapper::success($cacheData);

        //如果没有 从数据库里查一遍 存到redis 值返回
        $sql = "select `type`,count(id) as count from " . $this->objDInventoryOut->get_Table() . " GROUP BY `type`";
        $dbResult = $this->objDInventoryOut->query($sql);//销售出库
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        $typeData = [];
        foreach ($dbResult as $value) {
            $typeData[$value['type']] = $value['count'];
        }
        $cacheData = [];
        $cacheResult = $objCacheStock->deleteCacheStatistics($cacheKey);
        if (!$cacheResult && $cacheResult !== 0) {
            $this->objDInventoryOut->rollBack();
            return ResultWrapper::fail('删除缓存失败', ErrorCode::$paramError);
        }
        foreach ($type as $value) {
            $cacheData[] = [
                'type'  => $value,
                'count' => isset($typeData[$value]) ? $typeData[$value] : 0,
            ];
            if (isset($typeData[$value])) {
                $objCacheStock->createCacheStatistics($value, $typeData[$value], $cacheKey);
            }
        }
        return ResultWrapper::success($cacheData);
    }

    /**
     * 出库详情
     * @param $params
     * @return ResultWrapper
     * @throws Exception
     */
    public function getInventoryOutInfo($params)
    {
        // 查询出库单数据
        $params['deleteStatus'] = StatusCode::$standard;
        $dbResult = $this->objDInventoryOut->get($params);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            return ResultWrapper::fail('查询单据不存在', ErrorCode::$dberror);
        }

        // 查询出库单明细数据
        $dbResult['details'] = $this->objDInventoryOutDetails->select(['linkId' => $dbResult['id']]);
        if ($dbResult['details'] === false) {
            return ResultWrapper::fail($this->objDInventoryOutDetails->error(), ErrorCode::$dberror);
        }

        // 格式化 extend
        if (!empty($dbResult['extend'])){
            $dbResult['extend'] = json_decode($dbResult['extend'],true);
        }

        // 提取skuid 和 物料id
        $skuIds = array_column($dbResult['details'], 'skuId');
        $materielIds = array_column($dbResult['details'], 'materielId');

        // 查询订单商品表对应商品数据
        $objMOrderGoods = new MOrderGoods($this->userCenterId,$this->enterpriseId);
        if (isset($params['materielId'])){
            $skuValueResult = $objMOrderGoods->formatSkuValue($dbResult['details'],'materielId','skuId',$dbResult['shopId']);
            if (!$skuValueResult->isSuccess()){
                return ResultWrapper::fail($skuValueResult->getData(),$skuValueResult->getErrorCode());
            }
            $dbResult['details'] = $skuValueResult->getData();
        }

        //每个物料的仓库分布
        $dbResult['skuWarehouseData'] = [];
        unset($modelResult);
        //未出库物料数据
        $dbResult['outWarehouseData'] = [];
        //未分配物料数据
        $dbResult['UnassignedSkuData'] = [];
        //每个物料的待出库总数
        $dbResult['skuTotal'] = [];

        $objMShop = new MShop($this->enterpriseId,$this->userCenterId);

        //判断该单据是否分配仓库
        if($dbResult['type'] == StatusCode::$orderType['saleOut'] && $dbResult['auditStatus'] == StatusCode::$auditStatus['auditing']){
            //分配出库
            $dbResult['isDistribution'] = 5;
            //查询商铺绑定仓库
            $modelResult = $objMShop->getShopBindWarehouse($dbResult['shopId']);
            if(!$modelResult->isSuccess()){
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $shop = $modelResult->getData();
            unset($modelResult);
            if(empty($shop)){
                return ResultWrapper::fail('商铺查询失败', ErrorCode::$dberror);
            }
            $warehouseData = $shop['warehouseData'];

            //获取库存分布
            $objMInventory = new MInventory($this->enterpriseId, $this->userCenterId);
            $modelResult = $objMInventory->getInventoryByShopIdAndSkuIds($dbResult['shopId'], $skuIds);
            if(!$modelResult->isSuccess()){
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $inventoryData = $modelResult->getData();
            $dbResult['skuWarehouseData'] = $inventoryData;

            //获取负库存设置
            $objMGoods = new MGoods($this->enterpriseId, false, $this->userCenterId);
            $modelResult = $objMGoods->getDistributionByShopIdRelMaterielIds($dbResult['shopId'], $materielIds);
            if(!$modelResult->isSuccess()){
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $preSale = $modelResult->getData();
            unset($modelResult);

            $dbResult = self::distributionOutInventory($dbResult, $inventoryData, $warehouseData, $preSale);
        }else{
            //不分配出库
            $dbResult['isDistribution'] = 4;

            //查询仓库数据
            $objMWarehouse = new MWarehouse($this->enterpriseId);
            $modelResult = $objMWarehouse->selectWarehouse();
            if(!$modelResult->isSuccess()){
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $warehouseResult = $modelResult->getData();
            unset($modelResult);
            $warehouseData = [];
            foreach($warehouseResult as $value){
                $warehouseData[$value['id']] = $value;
            }

            $dbResult = self::formatClassCompleteOutInventory($dbResult, $warehouseData);
        }


        $dbResult = parent::formatOrderMan($this->enterpriseId, $dbResult);
        //如果是销售出库单 需要格式化收货人信息 打印次数
        if($dbResult['type'] == StatusCode::$orderType['saleOut']){
            $modelResult = self::formatOrderInventoryOut($dbResult);
            if(!$modelResult->isSuccess()){
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
            $dbResult = $modelResult->getData();
            $objMPrintNum = new MPrintNum($this->enterpriseId);
            $modelResult = $objMPrintNum->getObjectPrintNum($dbResult['no'], $dbResult['type']);
            $dbResult['printTimes'] = $modelResult;
            $dbResult['printingNum'] = $modelResult;
            foreach($dbResult['details'] as &$value){
                $value['originTotalPrice'] = bcmul($value['unitPrice'], $value['num'],2);//原始总价
            }
            unset($value);
        }
        $dbResult['selfRuleData'] = [];
        if($dbResult['source'] == StatusCode::$orderType['saleOrder']){
            $ruleResult = self::formatSelfInfo($dbResult['sourceId']);
            if (!$ruleResult->isSuccess()){
                return ResultWrapper::fail($ruleResult->getData(),$ruleResult->getErrorCode());
            }
            $dbResult['selfRuleData'] = empty($ruleResult->getData()) ? [] : $ruleResult->getData();
            $dbResult['receivedName'] = isset($dbResult['receiveData']['realName']) ? $dbResult['receiveData']['realName'] : '';
            $dbResult['receivedMobile'] = isset($dbResult['receiveData']['mobile']) ? $dbResult['receiveData']['mobile'] : '';
            $shopResult = $objMShop->getShopInfo(['id' => $dbResult['shopId']]);
            if (!$shopResult->isSuccess()){
                return ResultWrapper::fail($shopResult->getData(),$shopResult->getErrorCode());
            }
            $shopData = $shopResult->getData();
            $dbResult['shopMobile'] = isset($shopData['mobile']) ? $shopData['mobile'] : '';
            $dbResult['shopAddress'] = isset($shopData['area']) ? $shopData['area'] : [];
            $dbResult['shopDescribe'] = isset($shopData['describe']) ? $shopData['describe'] : '';
        }
        if($dbResult['type'] == StatusCode::$orderType['allocateOut']){
            
            // 映射仓库名称
            $objMAllocate = new MAllocate($this->enterpriseId,$this->userCenterId);
            $data = $objMAllocate->getAllocateInfoByWarehouseName([$dbResult]);
            if(!$data->isSuccess()){
                return ResultWrapper::fail($objMAllocate->error(), ErrorCode::$dberror);
            }
            $dbResult = $data->getData();
                foreach ($dbResult as $key=>$value){
                    $dbResult[$key]['outWarehouseId'] = $dbResult[$key]['warehouseId'];
                    $dbResult[$key]['outWarehouseName'] = $dbResult[$key]['warehouseName'];
                
                    unset($dbResult[$key]['warehouseId']);
                    unset($dbResult[$key]['warehouseName']);
                }
                
            $dbResult = array_pop($dbResult);
            
        }
        
        return ResultWrapper::success($dbResult);
    }

    /**
     * 自动分配库存
     * @param $outInventory
     * @param $inventoryData
     * @param $warehouseData
     * @param $preSale
     * @return mixed
     */
    public function distributionOutInventory($outInventory, $inventoryData, $warehouseData, $preSale)
    {
        foreach($outInventory['details'] as $key => $value){
            $value['outWarehouse'] = !empty($value['outWarehouse']) ? json_decode($value['outWarehouse'], true) : [];
            $value['isPreSale'] = $preSale[$value['materielId']];//负库存
            $outInventory['details'][$key]['isPreSale'] = $preSale[$value['materielId']];//负库存
            $outInventory['skuTotal'][$value['skuId']] = $value['num'];//订单数量
            $outNum = $value['num'];
            $skuData = $value;
            $value['warehouseSelect'] = [];
            if(!isset($inventoryData[$value['skuId']])){
                continue;
            }
            //物料所在仓库数据
            $skuWarehouses = $inventoryData[$value['skuId']]['warehouseInventory'];

            //可选出库仓库
            foreach($skuWarehouses as $warehouseId => $skuWarehouse){
                $value['warehouseSelect'][] = [
                    'warehouseId' => $warehouseId,
                    'warehouseName' => $warehouseData[$warehouseId]['warehouseName'],
                    'warehouseInventoryNum' => $skuWarehouse['num']
                ];
            }

            //循环分配仓库
            foreach($skuWarehouses as $warehouseId => $skuWarehouse){
                if($outNum == 0){
                    //订单数量分配完仓库
                    break;
                }
                $value['warehouseId'] = $warehouseId;
                $value['warehouseName'] = $warehouseData[$warehouseId]['warehouseName'];

                if($skuWarehouse['num'] <= 0){
                    //仓库库存小于0
                    if($value['isPreSale'] == StatusCode::$standard){
                        //开启预售(负库存)
                        if(!isset($outInventory['outWarehouseData'][$warehouseId])){
                            $outInventory['outWarehouseData'][$warehouseId] = [
                                'warehouseId' => $warehouseId,
                                'warehouseName' => $warehouseData[$warehouseId]['warehouseName'],
                                'details' => []
                            ];
                        }
                        //仓库库存剩余=仓库库存-订单数量
                        $value['warehouseInventoryNum'] = bcsub($skuWarehouse['num'], $outNum, 8);
                        //出库数量就是订单数量
                        $outInventory['outWarehouseData'][$warehouseId]['details'][] = $value;
                        $outNum = 0;
                    }else{
                        //没有开启预售(负库存)
                        //跳过该仓库
                        continue;
                    }
                }else{
                    //仓库库存大于0
                    if($skuWarehouse['num'] >= $outNum){
                        //仓库库存大于订单数量
                        if(!isset($outInventory['outWarehouseData'][$warehouseId])){
                            $outInventory['outWarehouseData'][$warehouseId] = [
                                'warehouseId' => $warehouseId,
                                'warehouseName' => $warehouseData[$warehouseId]['warehouseName'],
                                'details' => []
                            ];
                        }
                        //仓库库存剩余=仓库库存-订单数量
                        $value['warehouseInventoryNum'] = bcsub($skuWarehouse['num'], $outNum, 8);
                        //出库数量=订单数量
                        $value['num'] = $outNum;

                        $outInventory['outWarehouseData'][$warehouseId]['details'][] = $value;
                        $outNum = 0;
                    }else{
                        //仓库数量小于订单数量
                        //判断是否开启预售
                        if($value['isPreSale'] == StatusCode::$standard){
                            //开启预售(负库存)
                            if(!isset($outInventory['outWarehouseData'][$warehouseId])){
                                $outInventory['outWarehouseData'][$warehouseId] = [
                                    'warehouseId' => $warehouseId,
                                    'warehouseName' => $warehouseData[$warehouseId]['warehouseName'],
                                    'details' => []
                                ];
                            }
                            //仓库库存剩余=仓库库存-订单数量
                            $value['warehouseInventoryNum'] = bcsub($skuWarehouse['num'], $outNum, 8);
                            //出库数量就是订单数量
                            $outInventory['outWarehouseData'][$warehouseId]['details'][] = $value;
                            $outNum = 0;
                        }else{
                            //没有开启预售(负库存)
                            if(!isset($outInventory['outWarehouseData'][$warehouseId])){
                                $outInventory['outWarehouseData'][$warehouseId] = [
                                    'warehouseId' => $warehouseId,
                                    'warehouseName' => $warehouseData[$warehouseId]['warehouseName'],
                                    'details' => []
                                ];
                            }
                            //仓库库存剩余=0
                            $value['warehouseInventoryNum'] = 0;

                            //出库数量=仓库库存
                            $value['num'] = $skuWarehouse['num'];
                            $outInventory['outWarehouseData'][$warehouseId]['details'][] = $value;
                            $outNum = bcsub($outNum, $skuWarehouse['num'],8);
                            continue;
                        }
                    }
                }
            }
            if($outNum > 0){
                $skuData['num'] = $outNum;
                $outInventory['UnassignedSkuData'][] = $skuData;
            }
        }
        $outInventory['outWarehouseData'] = array_values($outInventory['outWarehouseData']);

        return $outInventory;
    }

    /**
     * 格式化已完成出库单
     * @param $outInventory
     * @param $warehouseData
     * @return mixed
     */
    public function formatClassCompleteOutInventory($outInventory, $warehouseData)
    {
        foreach($outInventory['details'] as $value){
            //已出库数据
            $value['outWarehouse'] = !empty($value['outWarehouse']) ? json_decode($value['outWarehouse'], true) : [];
            $skuData = $value;
            foreach($value['outWarehouse'] as $outWarehouse){
                $warehouseId = $outWarehouse['warehouseId'];
                if(!isset($outInventory['outWarehouseData'][$warehouseId])){
                    $outInventory['outWarehouseData'][$warehouseId] = [
                        'warehouseId' => $warehouseId,
                        'warehouseName' => $warehouseData[$warehouseId]['warehouseName'],
                        'details' => []
                    ];
                }
                $value['num'] = $outWarehouse['num'];
                $value['warehouseId'] = $warehouseId;
                $value['warehouseName'] = $warehouseData[$warehouseId]['warehouseName'];
                $outInventory['outWarehouseData'][$warehouseId]['details'][] = $value;
            }
            //未出库数据
            if($skuData['num'] > 0){
                $outInventory['UnassignedSkuData'][] = $skuData;
            }
        }
        $outInventory['outWarehouseData'] = array_values($outInventory['outWarehouseData']);

        return $outInventory;
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/10/11
     * Time: 2:23 下午
     * @param $orderId
     * @throws Exception
     * @return ResultWrapper
     */
    public function formatSelfInfo($orderId)
    {
        $objDOrderIndex = new DOrderIndex();
        $objDOrderIndex->setTable('qianniao_order_index_'.$this->enterpriseId);
        $orderIndex = $objDOrderIndex->get(['id'=>$orderId]);
        if ($orderIndex===false){
            return ResultWrapper::fail($objDOrderIndex->error(),ErrorCode::$dberror);
        }
        if (empty($orderIndex)){
            return ResultWrapper::fail('获取订单信息失败',ErrorCode::$paramError);
        }
        if ($orderIndex['deliveryType'] != StatusCode::$deliveryType['selfMention']){
            return ResultWrapper::success([]);
        }
        $objDOrder = new DOrder();
        $fix = ceil($orderIndex['userCenterId'] / $this->cutTable);;
        $objDOrder->setTable('qianniao_order_'.$this->enterpriseId.'_'.$fix);
        $order = $objDOrder->get(['id' => $orderId]);
        if ($order === false){
            return ResultWrapper::fail($objDOrder->error(),ErrorCode::$dberror);
        }
        if (empty($order)){
            return ResultWrapper::fail('获取订单信息失败',ErrorCode::$paramError);
        }
        $rule = empty($order['selfRuleData']) ? (object)[] : json_decode($order['selfRuleData'],true);
        return ResultWrapper::success($rule);
    }



    /**
     * 查询出库数据
     * @param $where
     * @return ResultWrapper
     */
    public function getInventoryOutData($where)
    {
        $dbResult = $this->objDInventoryOut->select($where);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 格式化商品货架码 商品条码
     * @param $params
     * @param string $materielIdKey
     * @return ResultWrapper
     * @throws Exception
     */
    public function formatOutDetails($params, $materielIdKey = 'materielId')
    {
        foreach($params['details'] as &$value){
            if(isset($value['storageCode']) && empty($value['storageCode'])){
                $value['skuStorage'] = $value['storageCode'];
            }else{
                if(!isset($value['skuStorage']) || empty($value['skuStorage'])){
                    $materielIds[] = $value[$materielIdKey];
                }
            }
        }
        unset($value);
        if(empty($materielIds)){
            return ResultWrapper::success($params);
        }
        $objDGoodsBasic = new DGoodsBasic();
        $sql = 'select * from qianniao_goods_basic_'.$this->enterpriseId.' where id in('.implode(',', $materielIds).')';
        $dbResult = $objDGoodsBasic->query($sql);
        if($dbResult === false){
            return ResultWrapper::fail($objDGoodsBasic->error(), ErrorCode::$dberror);
        }

        $format = [];
        foreach($dbResult as $value){
            $format[$value['id']] = '';
            if(!empty($value['extends'])){
                $extends = json_decode($value['extends'], true);
                if(isset($extends['storage']) && !empty($extends['storage'])){
                    $format[$value['id']] = $extends['storage'];
                }
            }
        }
        unset($value);
        foreach($params['details'] as &$value){
            $value['skuStorage'] = isset($format[$value[$materielIdKey]]) ? $format[$value[$materielIdKey]] : '';
        }
        return ResultWrapper::success($params);
    }

    /**
     * 格式化销售出库单
     * @param $data
     * @return ResultWrapper
     * @throws Exception
     */
    public function formatOrderInventoryOut($data)
    {
        if(empty($data)) return ResultWrapper::success($data);
        //查询订单
        $objMOrder = new MOrder($this->userCenterId, $this->enterpriseId);
        $modelResult = $objMOrder->getOrderInfoById($data['originId']);
        if(!$modelResult->isSuccess()){
            return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
        }
        $orderData = $modelResult->getData();
        $data['deliveryName'] = $orderData['deliveryName'];//配送方式名称
        $data['receiveData'] = $orderData['receiveData'];//收货信息
        return ResultWrapper::success($data);
    }

    /**
     * 查询采购退货记录
     * @param $params
     * @return ResultWrapper
     */
    public function getPurchaseReturnData($params)
    {
        if (empty($params)) return ResultWrapper::success([]);
        $originIds = [];
        $materielIds = [];
        foreach ($params as $value) {
            $originIds[] = $value['id'];
            $materielIds[] = $value['materielId'];
        }
        $sql = 'select i.originId,d.materielId,d.num from ' . $this->objDInventoryOut->get_Table() . ' i left join ' . $this->objDInventoryOutDetails->get_Table() . ' d on i.id = d.linkId where i.auditId = ' . StatusCode::$auditStatus['auditPass'] . ' and i.type = ' . StatusCode::$orderType['purchaseReturnOut'] . ' and i.originId in(' . implode(",", $originIds) . ') and d.materielId in(' . implode(",", $materielIds) . ')';
        $dbResult = $this->objDInventoryOut->query($sql);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        $formatData = [];
        foreach ($dbResult as $value) {
            $formatData[md5($value['originId'] . $value['materielId'])] = $value;
        }
        unset($dbResult);
        return ResultWrapper::success($formatData);
    }

    /**
     * 查询出库数据
     * @param $where
     * @param string $fields
     * @param string $order
     * @param array $limits
     * @return ResultWrapper
     */
    public function getOutData($where, $fields = '*', $order = 'id asc', $limits = [])
    {
        if ($limits) {
            $limit = $limits['limit'];
            unset($limits['limit']);
            $offset = $limits['offset'];
            unset($limits['offset']);
            $dbResult = $this->objDInventoryOutDetails->select($where, $fields, $order, $limit, $offset);
        } else {
            $dbResult = $this->objDInventoryOutDetails->select($where, $fields, $order);
        }
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDInventoryOutDetails->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 统计订单未出库总数
     * @param int $shopId
     * @return ResultWrapper
     */
    public function statisticsCountInventoryOut($shopId = 0)
    {
        if(empty($shopId)) $shopId = 0;
        $objOverviewCache = new OverviewCache();
        $result = $objOverviewCache->getStatisticsCountInventoryOut($this->enterpriseId, $shopId);
        if($result){
            return ResultWrapper::success($result);
        }
        $where = [
            'auditStatus' => StatusCode::$auditStatus['auditing'],
            'deleteStatus' => StatusCode::$standard,
            'source' => StatusCode::$orderType['saleOrder'],
        ];
        $dbResult = $this->objDInventoryOut->count($where);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        $allCount = $dbResult;
        unset($dbResult);
        $objOverviewCache->setStatisticsCountInventoryOut($this->enterpriseId, $shopId, $allCount);

        if($shopId){
            $where['shopId'] = $shopId;
            $dbResult = $this->objDInventoryOut->count($where);
            if($dbResult === false){
                return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
            }
            $shopCount = $dbResult;
            unset($dbResult);
            $objOverviewCache->setStatisticsCountInventoryOut($this->enterpriseId, $shopId, $shopCount);
            return ResultWrapper::success($shopCount);
        }

        return ResultWrapper::success($allCount);
    }

    /**
     * 添加es
     * @param $data
     * @param $id
     * @param bool $type
     * @return ResultWrapper
     */
    public function updateEsData($data, $id, $type = false)
    {
        $addEsData = [
            'id'             => $id,
            'enterpriseId'   => $this->enterpriseId,
            'no'             => isset($data['no']) ? StatusCode::$noPrefix[$data['type']].$data['no'] : false,
            'sourceId'       => isset($data['sourceId']) ? $data['sourceId'] : false,
            'sourceNo'       => isset($data['sourceNo']) ? StatusCode::$noPrefix[$data['source']].$data['sourceNo'] : false,
            'originId'       => isset($data['originId']) ? $data['originId'] : false,
            'originNo'       => isset($data['originNo']) ? StatusCode::$noPrefix[$data['source']].$data['originNo'] : false,
            'materielNum'    => isset($data['materielNum']) ? $data['materielNum'] : false,
            'amount'         => isset($data['amount']) ? $data['amount'] : false,
            'warehouseId'    => isset($data['warehouseId']) ? $data['warehouseId'] : false,
            'warehouseName'  => isset($data['warehouseName']) ? $data['warehouseName'] : false,
            'operatorId'     => isset($data['operatorId']) ? $data['operatorId'] : false,
            'operatorName'   => isset($data['operatorName']) ? $data['operatorName'] : false,
            'auditId'        => isset($data['auditId']) ? $data['auditId'] : false,
            'auditName'      => isset($data['auditName']) ? $data['auditName'] : false,
            'customerId'     => isset($data['customerId']) ? $data['customerId'] : false,
            'customerName'   => isset($data['customerName']) ? $data['customerName'] : false,
            'customerCode'   => isset($data['customerCode']) ? $data['customerCode'] : false,
            'customerMobile' => isset($data['customerMobile']) ? $data['customerMobile'] : false,
            'remark'         => isset($data['remark']) ? $data['remark'] : false,
            'source'         => isset($data['source']) ? $data['source'] : false,
            'type'           => isset($data['type']) ? $data['type'] : false,
            'deliveryType'   => isset($data['deliveryType']) ? $data['deliveryType'] : false,
            'deleteStatus'   => isset($data['deleteStatus']) ? $data['deleteStatus'] : false,
            'auditStatus'    => isset($data['auditStatus']) ? $data['auditStatus'] : false,
            'auditTime'      => isset($data['auditTime']) ? $data['auditTime'] : false,
            'createTime'     => isset($data['createTime']) ? $data['createTime'] : false,
            'updateTime'     => isset($data['updateTime']) ? $data['updateTime'] : false,
        ];

        foreach ($addEsData as $key => $value) {
            if ($value === false) {
                if ($type) {
                    return ResultWrapper::fail($key . '字段未设置', ErrorCode::$paramError);
                } else {
                    unset($addEsData[$key]);
                }
            }
        }

        //创建es id
        $esId = self::esId($id);
        $result = $this->objDInventoryOut->addUpSearchIndexDocument($addEsData, $esId);
        if (isset($result['_shards']) && isset($result['_shards']['successful']) && $result['_shards']['successful'] == 1) {
            return ResultWrapper::success(isset($result['_id']) ? $result['_id'] : false);
        }
        return ResultWrapper::fail($result['error']['reason'], ErrorCode::$paramError);
    }

    /**
     * 修改es
     * @param $update
     * @param $id
     * @return ResultWrapper
     */
    public function updateEs($update, $id)
    {
        $esId = self::esId($id);
        $result = $this->objDInventoryOut->esupdateTypeFieldVaule($update, $esId);
        if (isset($result['_shards']) && isset($result['_shards']['successful']) && $result['_shards']['successful'] == 1) {
            return ResultWrapper::success(isset($result['_id']) ? $result['_id'] : false);
        }
        return ResultWrapper::fail($result['error']['reason'], ErrorCode::$paramError);
    }

    /**
     * 拼接es id
     * @param $id
     * @return string
     */
    public function esId($id)
    {
        return 'EnterpriseId_' . $this->enterpriseId . '_InventoryOutId_' . $id;
    }


    /**
     * 格式化出库es
     */
    public function formatInventoryOutEsData()
    {
        //查询列表数据
        $dbResult = $this->objDInventoryOut->select([],'*');
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            return ResultWrapper::fail('格式化数据为空', ErrorCode::$dberror);
        }
        //循环插入es
        foreach($dbResult as $value){
            //增加es搜索
            $modelResult = self::updateEsData($value, $value['id'], true);
            if(!$modelResult->isSuccess()){
                return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
            }
        }
        return ResultWrapper::success('格式化成功');
    }

    /**
     * 设置物流信息
     */
    public function addLogistics($params)
    {
        if( !isset($params['id']) ){
            return ResultWrapper::fail('出库单id参数错误',ErrorCode::$paramError);
        }

        $id = $params['id'];
        unset($params['id']);

        $extend = [];
        $dbResult = $this->objDInventoryOut->get($id);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        if( empty($dbResult) ){
            return ResultWrapper::fail('要查询的出库单信息为空', ErrorCode::$contentNotExists);
        }

        // 如果司机是手动收入的，先做新增操作
        if( empty($params['driverId']) ){
            $objMDriver = new MDriver($this->enterpriseId, $this->userCenterId);
            $paramsDriver = [
                'enterpriseId'=> $this->enterpriseId,
                'driverName'  => $params['driverName'],
                'phone'       => $params['truckTel'],
                'plateNumber' => $params['truckName'],
                'remark'      => $params['remark']
            ];
            $addDriver = $objMDriver->addDriver($paramsDriver);
            if ( !$addDriver->isSuccess() ){
                return ResultWrapper::fail($addDriver->getData(),$addDriver->getErrorCode());
            }
            $driverId = $addDriver->getData();
            $params['driverId']= $driverId;
        }

        $extend['logistics'] = $params;
        $updateLogistics = $this->objDInventoryOut->update(['extend'=>json_encode($extend)]);
        if($updateLogistics === false){
            return ResultWrapper::fail($this->objDInventoryOut->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($updateLogistics);
    }

    /**
     * 扫条码加载出库单商品数据
     */
    public function getDetailByGoodsCode($params)
    {
        $objDSku = new DSku('default');
        $objDSku->set_Table('qianniao_sku_'.$this->enterpriseId);
        $dbResult = $objDSku->get(['barCode'=>$params['barCode']]);
        if($dbResult === false){
            return ResultWrapper::fail($objDSku->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            return ResultWrapper::fail('条码对应商品为空', ErrorCode::$contentNotExists);
        }

        // 查询商品是否支持负库存销售
        $objDGoods = new DGoods('default');
        $objDGoods->set_Table('qianniao_goods_'.$this->enterpriseId);
        $condition = [
            'basicGoodsId' => $dbResult['goodsId'],
            'deleteStatus' => StatusCode::$standard,
        ];
        $goodsData = $objDGoods->get($condition);
        if($goodsData === false){
            return ResultWrapper::fail($objDGoods->error(), ErrorCode::$dberror);
        }
        if(empty($goodsData)){
            return ResultWrapper::fail('商品数据为空', ErrorCode::$contentNotExists);
        }

        // 查询出库单明细数据
        $condition = [
            'skuId'  => $dbResult['id'],
            'linkId' => $params['id'],
        ];
        $dbResult = $this->objDInventoryOutDetails->select($condition);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDInventoryOutDetails->error(), ErrorCode::$dberror);
        }

        $dbResult = parent::formatOrderMan($this->enterpriseId, $dbResult);

        // 格式化负库存销售
        foreach ($dbResult as $key => $value){
            $dbResult[$key]['isDistribution'] = $goodsData['isDistribution'];
        }

        return ResultWrapper::success($dbResult);
    }
}