<?php

namespace App\Services;

use App\Commodity;
use App\OracleActAllocationDetails;
use App\OracleBasSKU;
use App\OracleDOCOrderDetail;
use App\OracleDOCOrderHeader;
use App\Order;
use App\OrderPackage;
use App\OrderPackageCommodities;
use App\OrderTracking;
use App\Owner;
use App\Services\common\BatchUpdateService;
use App\Services\common\DataHandlerService;
use Carbon\Carbon;
use Illuminate\Support\Collection;

class OrderPackageCommoditiesService
{

    public function insert(array $params){
        return OrderPackageCommodities::query()->insert($params);
    }

    public function batchUpdate($params){
        return app(BatchUpdateService::class)->batchUpdate('order_package_commodities',$params);
    }
    //-------------------------
    public function basedOnOracleDetailsStore($orderNo, $orderPackage)
    {
        $details = OracleDOCOrderDetail::query()->where('orderNo', $orderNo)->get();
        $orderPackageCommodities = OrderPackageCommodities::query()->where('order_package_id',$orderPackage['id'])->get();
        $this->根据详情更新OrderPackage下的商品信息($orderPackage,$orderPackageCommodities,$details,'qtyordered');
        unset($details,$orderPackageCommodities);
    }

    public function basedOnActAllocationDetailsStoreByOrderNo($orderNo,$orderPackage){
        $details = OracleActAllocationDetails::query()->where('orderno', $orderNo)->get();
        $orderPackageCommodities =  OrderPackageCommodities::query()->where('order_package_id',$orderPackage['id'])->get();
        $this->根据详情更新OrderPackage下的商品信息($orderPackage,$orderPackageCommodities,$details,'qty_each');
        unset($details,$orderPackageCommodities);
    }

    public function 根据详情更新OrderPackage下的商品信息($orderPackage,$orderPackageCommodities,$details,$key){
        $newItems = [];
        foreach ($details as $detail) {
            $owner = Owner::query()->where(['code' => $detail['customerid']])->first();      // 货主
            $sku = $detail->sku;    // sku
            $owner_id = $owner->id; // 货主id
            $commodity = Commodity::query()->where(['sku' => $sku, 'owner_id' => $owner_id])->first(); // 商品
            if ($commodity == null) {
                $basSku = OracleBasSKU::query()->where(['sku' => $sku, 'customerid' => $detail->customerid])->first();   // 没有找到对应的商品信息
                $commodity = Commodity::query()->create(['sku' => $sku, 'owner_id' => $owner_id, 'name' => $basSku->descr_c]);
            }
            $data =  ['order_package_id' => $orderPackage['id'], 'commodity_id' => $commodity['id'], 'amount' => $detail[$key]];
            array_push($newItems,$data);
        }
        $diffarr = [];
        foreach ($newItems as $newItem) {
            $packageCommodity =  $orderPackageCommodities->where('order_package_id',$newItem['order_package_id'])->where('commodity_id',$newItem['commodity_id'])->first();
            if($packageCommodity!=null){
                if($packageCommodity['amount'] != $newItem['amount']){
                    $packageCommodity->update(['amount'=>intval($newItem['amount'])]);
                }
                $orderPackageCommodities =  $orderPackageCommodities->filter(function ($item) use ($packageCommodity){
                    if($item['id'] == $packageCommodity['id']){
                        return false;
                    }
                    return true;
                });
                array_push($diffarr,$newItem);
            }
        }
        if($orderPackageCommodities->count() > 0){
            foreach ($orderPackageCommodities as $orderPackageCommodity) {
                $id = $orderPackageCommodity['id'];
                OrderPackageCommodities::destroy($id);
            }
        }
        $newItems = array_filter($newItems,function($newItem) use ($diffarr){
            foreach ($diffarr as $item) {
                if($item['order_package_id'] == $newItem['order_package_id'] &&
                    $item['commodity_id'] == $newItem['commodity_id'] &&
                    $item['amount'] == $newItem['amount']){
                    return false;
                }
            }
            return true;
        });
        try {
            if(count($newItems) > 0 ){
                OrderPackageCommodities::query()->insert($newItems);
                app('LogService')->log(__METHOD__,__FUNCTION__,'添加包裹商品信息'.json_encode($newItems));
            }
        } catch (\Exception $e) {
            app('LogService')->log(__METHOD__,__FUNCTION__,'添加包裹商品信息异常'.json_encode($newItems).$e->getMessage(),$e->getTraceAsString());
        } finally {
            unset($newItems,$orderPackageCommodities);
        }
    }

    public function basedOnActAllocationDetailsStore($orderPackage)
    {
        $details = OracleActAllocationDetails::query()->where('picktotraceid', $orderPackage->logistic_number)->get();
        $orderPackageCommodities =  OrderPackageCommodities::query()->where('order_package_id',$orderPackage['id'])->get();
        $this->根据详情更新OrderPackage下的商品信息($orderPackage,$orderPackageCommodities,$details,'qty_each');
        unset($details,$orderPackageCommodities);
    }

/*    public function basedOnActAllocationDetail(Order $order, OracleDOCOrderHeader $header, array $details)
    {
        foreach ($details as $detail) {
            $logistic_number = $details['picktotraceid'];
            if ($logistic_number == '*' || $logistic_number == null || $logistic_number == '') {
                $logistic_number = $header['soreference5'];
                if ($logistic_number == '*' || $logistic_number == null || $logistic_number == '') {
                    continue;
                }
            }
            $orderPackage = OrderPackage::query()->firstOrCreate(['order_id'=>$order['id'],'logistic_number',$details]);
            $this->createByActAllocationDetail($detail, $orderPackage);
        }
    }*/

   /* private function createByActAllocationDetail($detail,$orderPackage)
    {
        $owner = Owner::query()->where(['code' => $detail->customerid])->first();      // 货主
        $sku = $detail->sku;
        $owner_id = $owner['id'];
        $commodity = Commodity::query()->where(['sku' => $sku, 'owner_id' => $owner_id])->first();
        if ($commodity == null) {
            $basSku = OracleBasSKU::query()->where(['sku' => $sku, 'customerid' => $detail->customerid])->first();
            $commodity = Commodity::query()->create(['sku' => $sku, 'owner_id' => $owner_id, 'name' => $basSku->descr_c]);
        }
        try {
            $count  = OrderPackageCommodities::query()->where(['order_package_id' => $orderPackage['id'], 'commodity_id' => $commodity['id'], 'amount' => $detail['qty_each']])->count();
            if($count == 0){
                $orderPackageCommodities = OrderPackageCommodities::query()->firstOrCreate(['order_package_id' => $orderPackage['id'], 'commodity_id' => $commodity['id'], 'amount' => $detail['qty_each']]);
                app('LogService')->log(__METHOD__,__FUNCTION__,'创建订单包裹详情'.json_encode($orderPackageCommodities));
            }
        } catch (\Exception $e) {
            app('LogService')->log(__METHOD__,__FUNCTION__,'创建订单包裹失败'.$e->getMessage().$e->getTraceAsString());
        } finally {
            return $orderPackageCommodities ?? null;
        }
    }*/

    public function createByWmsOrder($orderHeaders)
    {
        if(!$orderHeaders){ return [];}
        $this->更新OPC_根据WMS订单($orderHeaders);
    }

//    public function getParamsByActAllocationDetails($details,array $order_packages_logistic_number_map,array $owner_code_map,array $commodity_owner_id_sku_map,array $logistic_numbers){
//        /** @var DataHandlerService  $dataHandlerService */
//        $dataHandlerService =  app(DataHandlerService::class);
//        if(!$details)return [];
//        $params = [];
//        $create_at = Carbon::now()->format('Y-m-d H:i:s');
//        $updated_at = Carbon::now()->format('Y-m-d H:i:s');
//        foreach ($details as $actAllocationDetail) {
//            $pickToTraceID = $actAllocationDetail->picktotraceid;
//            if(in_array($pickToTraceID,$logistic_numbers)){
//                $orderPackage = $dataHandlerService->getKeyValue(['logistic_number'=>$pickToTraceID],$order_packages_logistic_number_map);
//                if(!$orderPackage)continue;
//                $owner = $dataHandlerService->getKeyValue(['code'=>$actAllocationDetail->customerid],$owner_code_map);
//                if(!$owner)continue;
//                $commodity = $dataHandlerService->getKeyValue(['owner_id'=>$owner->id,'sku'=>$actAllocationDetail->sku],$commodity_owner_id_sku_map);
//                if(!$commodity)continue;
//                $params[] = [
//                    'commodity_id' =>$commodity->id,
//                    'order_package_id' =>$orderPackage->id,
//                    'amount' => $actAllocationDetail->qty_each,
//                    'created_at' => $create_at
//                ];
//            }
//        }
//        unset($details,$order_packages_logistic_number_map,$owner_code_map,$commodity_owner_id_sku_map,$logistic_numbers);
//        return $params;
//    }

    public function create(array $params){
        if(!$params){return [];}
        try {
            $this->insert($params);
            app('LogService')->log(__METHOD__,__FUNCTION__,'批量创建 OrderPackageCommodities'.count($params).json_encode($params));
        } catch (\Exception $e) {
            app('LogService')->log(__METHOD__,__FUNCTION__,'批量创建 OrderPackageCommodities error'.json_encode($params)."||".$e->getMessage().'||'.$e->getTraceAsString());
        } finally {
            $order_package_ids = array_unique(data_get($params,'*.order_package_id'));
            unset($params);
            return OrderPackageCommodities::query()
                ->with('commodity')
                ->whereIn('order_package_id',$order_package_ids)
                ->get();
        }
    }

    public function updateByWmsOrder($orderHeaders){
        if(!$orderHeaders){return ;}
        $this->更新OPC_根据WMS订单($orderHeaders);
    }

    public function getByWmsOrder($orderHeaders){
        $order_no =  data_get($orderHeaders,'*.orderno');
        return OrderPackageCommodities::query()
            ->with('package.order','commodity')
            ->whereHas('package.order',function($query) use ($order_no){
                $query->whereIn('code',$order_no);
            })->get();
    }

    public function batchUpdateItself($column, array $params)
    {
        return app(BatchUpdateService::class)->batchUpdateItself('order_package_commodities', $column, $params);
    }

    /**
     * @param array $logistic_numbers
     * @return array|mixed
     */
    public function 删除包裹商品信息_根据快递单号($logistic_numbers)
    {
        $orderPackageCommodities = OrderPackageCommodities::query()->with('package')->whereHas('package',function($query)use($logistic_numbers){
            $query->whereIn('logistic_number',$logistic_numbers);
        })->get();
        $ids = data_get($orderPackageCommodities, '*.id');
        if(count($ids) == 0){return [];}
        try {
            OrderPackageCommodities::query()->whereIn('id', $ids)->delete();
            app('LogService')->log(__METHOD__,__FUNCTION__,'删除多余OrderPackageCommodities '.$orderPackageCommodities->count().json_encode($orderPackageCommodities),null);
        } catch (\Exception $e) {
            app('LogService')->log(__METHOD__,__FUNCTION__,'删除多余OrderPackageCommodities error'.$orderPackageCommodities->count().json_encode($orderPackageCommodities).$e->getMessage().$e->getTraceAsString(),null);
            return [];
        }
        return $ids;
    }

    /**
     * @param array $orderNos
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public function getByOrderNos($orderNos)
    {
        return OrderPackageCommodities::query()->with('package.order','commodity')
            ->whereHas('package.order',function($query) use ($orderNos){
                $query->whereIn('code',$orderNos);
            })->get();
    }

    /**
     * @param Collection $orders
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public function getByOrders($orders)
    {
        return $this->getByOrderNos(data_get($orders,'*.code'));
    }

    /**
     * @param OracleDOCOrderHeader $orderHeader
     * @param Order $order
     * @return array|Collection|\Tightenco\Collect\Support\Collection
     */
    public function 返回创建数组($orderHeader)
    {
        if($orderHeader->sostatus == 90){return [];}
        $actAllocationDetails = $orderHeader->actAllocationDetails->collect();
        $innerParams = collect();
        $actAllocationDetails->each(function($detail)use(&$innerParams){
            $sku =  $detail->sku;
            $amount =  $detail->qty_each;
            $logistic_number = $detail->picktotraceid;
            $params = [
                'ownerCode' => $detail->customerid,
                'orderNo' => $detail->orderno,
                'sku' => $sku,
                'amount' => $amount,
                'logistic_number' => $logistic_number,
            ];

            $innerParam = $innerParams->where('logistic_number',$logistic_number)->where('sku',$sku)->first();
            if($innerParam ?? false){
                $bool = false;
                $innerParams = $innerParams->map(function($param)use($innerParam,$amount,&$bool){
                    if($innerParam['logistic_number'] == $param['logistic_number'] &&
                        $innerParam['sku'] == $param['sku'] && !$bool){
                        $param['amount'] += $amount;
                        $bool = !$bool;
                    }
                    return $param;
                });
            }else{
                $innerParams->push($params);
            }
        });
        return $innerParams;
    }

    public function 返回创建数组_WMS订单($orderHeaders)
    {
        $innerParams = [];
        foreach ($orderHeaders as $orderHeader) {
            $innerParam = $this->返回创建数组($orderHeader);
            foreach ($innerParam as $param) {
                $innerParams[] = $param;
            }
        }
        return $innerParams;
    }
    /**
     * @param array $innerParams
     * @return array
     */
    public function 生成OrderPackageCommodities_基于创建数组($innerParams)
    {
        if(!$innerParams){return [];}
        if(is_array($innerParams) && count($innerParams) == 0){return [];}
        $commodity_map = $this->返回Commodity数组_根据数组中sku($innerParams);
        $orderPackages_map = app(OrderPackageService::class)->返回OrderPackage数组_根据数组中的快递单号($innerParams);
        $createParams = [];
        $dataTime = Carbon::now()->format('Y-m-d H:i:s');
        foreach ($innerParams as $innerParam) {
            $key = ' ownerCode='.($innerParam['ownerCode'] ?? '').' sku='.($innerParam['sku'] ?? '');
            $commodity = $commodity_map[$key] ?? null;
            $orderPackage = $orderPackages_map[$innerParam['logistic_number']] ?? '';
            $createParams[] = [
                'order_package_id' => $orderPackage->id ?? '',
                'commodity_id' => $commodity->id ?? null,
                'amount' => $innerParam['amount'],
                'created_at' => $dataTime,
                'updated_at' => $dataTime,
            ];
        }
        return $createParams;
    }

    /**
     * @param $orderHeaders
     */
    public function 更新OPC_根据WMS订单($orderHeaders)
    {
        if(!$orderHeaders){return ;}
        if(count($orderHeaders) == 0){return ;}
        app(CommodityService::class)->getByWmsOrders($orderHeaders);
        $orderPackageCommodities = $this->getByWmsOrder($orderHeaders);
        $OPCCollects = $this->将orderPackageCommodity抽象成数组($orderPackageCommodities);
        $creatParams = $this->返回创建数组_WMS订单($orderHeaders);
        $orderNos = $this->数据重组($OPCCollects,$creatParams);
        $updateParams= collect();$deleteIds = [];$insertParams =[];
        foreach ($orderNos as $orderNo) {
            $OPCCollect = $OPCCollects[$orderNo] ?? null;
            $creatParam = $creatParams[$orderNo];
            $retain[] = $this->删选可以保留的OrderPackageCommodities($OPCCollect,$creatParam);

            $collect = $this->删选需要修改的OrderPackageCommodities($OPCCollect,$creatParam);

            $ids = $this->删选出删除的OrderPackageCommodities($OPCCollect,$creatParam);

            $insertParam = $this->删选出需要添加的OrderPackageCommodities($OPCCollect,$creatParam);

            $deleteIds = array_merge($deleteIds,$ids);

            foreach ($collect as $item) {
                $updateParams->push($item);
            }
            foreach ($insertParam as $item) {
                $insertParams[]= $item;
            }

        }
        $this->根据更新数组进行更新($updateParams);
        $this->删除OPC以及对应的追踪件($deleteIds);
        $creatParams = $this->生成OrderPackageCommodities_基于创建数组($insertParams);
        $this->create($creatParams);
    }

    /**
     * @param Collection $orderPackageCommodities
     * @return Collection|\Tightenco\Collect\Support\Collection
     */
    public function 将orderPackageCommodity抽象成数组($orderPackageCommodities)
    {
        /** @var DataHandlerService $dataHandlerService */
        $dataHandlerService = app(DataHandlerService::class);
        $collect = collect();
        $ownerIds = array_unique(data_get($orderPackageCommodities,'*.commodity.owner_id'));
        $owners = Owner::query()->whereIn('id',$ownerIds)->get();
        $owner_id_map = $dataHandlerService->dataHeader(['id'],$owners);
        foreach ($orderPackageCommodities as $orderPackageCommodity) {
            $owner = $dataHandlerService->getKeyValue(['id'=>$orderPackageCommodity->commodity->owner_id ?? ''],$owner_id_map);
            $params = [
                'id' => $orderPackageCommodity->id,
                'ownerCode' => $owner->code,
                'orderNo' => $orderPackageCommodity->package->order->code,
                'sku' => $orderPackageCommodity->commodity->sku,
                'amount' => $orderPackageCommodity->amount,
                'logistic_number' => $orderPackageCommodity->package->logistic_number,
            ];
            $collect->push($params);
        }
        return $collect;
    }

    public function 数据重组(&$OPCCollects,&$params)
    {
        $collect_map = [];$params_map = [];$order_no_map = [];

        foreach ($OPCCollects as $item) {
            $orderNo = $item['orderNo'];
            if(!isset($collect_map[$orderNo])){$collect_map[$orderNo] = collect();}
            $collect_map[$orderNo]->push($item);
        }

        foreach ($params as $param) {
            $orderNo =  $param['orderNo'];
            if(!isset($params_map[$orderNo])){$params_map[$orderNo] = collect();}
            $order_no_map[] = $orderNo;
            $params_map[$orderNo]->push($param);
        }
        $order_no_map = array_unique($order_no_map);
        $OPCCollects = $collect_map;
        $params = $params_map;
        return $order_no_map;
    }

    public function 删选可以保留的OrderPackageCommodities(&$OPCCollect,&$params)
    {
        $retain = collect();
        if($OPCCollect == null){return $retain;}
        $map = [];
        foreach ($params as $param) {
            $key = ' logistic_number='.$param['logistic_number'].' sku='.$param['sku'].' amount='.$param['amount'];
            if(! isset($map[$key])){
                $map[$key] = [];
            }
            $map[$key][] = $param;
        }

        foreach ($OPCCollect as $item) {
            $key = ' logistic_number='.$item['logistic_number'].' sku='.$item['sku'].' amount='.$item['amount'];
            if(isset($map[$key]) && count($map[$key]) > 0){
                $value = $map[$key][0];
                array_shift($map[$key]);
                $params->filter(function($param)use($value){
                    return count(array_diff_assoc($param,$value)) != 0 ;
                });
                $retain->push($value);
            }
        }

        return $retain;
    }

    public function 删选出需要添加的OrderPackageCommodities(&$OPCCollect,&$params)
    {
        $innerParam = [];
        $OPCmap = [];
        if($OPCCollect == null){return $params;}
        foreach ($OPCCollect as $item) {
            $key = ' logistic_number='.$item['logistic_number'].' sku='.$item['sku'].' amount='.$item['amount'];
            if(!isset($OPCmap[$key])){
                $OPCmap[$key][] = [];
            }
            $OPCmap[$key][] = $item;
        }
        $paramsMap = [];
        foreach ($params as $param) {
            $key = ' logistic_number='.$param['logistic_number'].' sku='.$param['sku'].' amount='.$param['amount'];
            if(!isset($OPCmap[$key])){
                $paramsMap[$key][] = [];
            }
            $paramsMap[$key][] = $param;
        }
        $paramsCopy = $params->collect();
        foreach ($paramsCopy as $param) {
            $key = ' logistic_number='.$param['logistic_number'].' sku='.$param['sku'].' amount='.$param['amount'];
            if(!(isset($OPCmap[$key]) && count($OPCmap[$key]) == 0)){
                $innerParam[] = $param;
                $OPCCollect->filter(function($item)use($param){
                    return !($item['logistic_number'] == $param['logistic_number'] &&$item['sku'] == $param['sku'] &&$item['amount'] == $param['amount'])  ;
                });
            }
        }
        return $innerParam;
    }

    public function 删选需要修改的OrderPackageCommodities(&$OPCCollect,&$params)
    {
        $update = collect();
        $map = [];
        if($OPCCollect == null){return $update;}
        foreach ($OPCCollect as $item) {
            $key = ' logistic_number='.$item['logistic_number'].' sku='.$item['sku'];
            if(!isset($map[$key])){$map[$key] = [];}
            $map[$key][] = $item;
        }
        $paramsCopy = $params->collect();
        foreach ($paramsCopy as $param) {
            $key = ' logistic_number='.$param['logistic_number'].' sku='.$param['sku'];
            if(!isset($map[$key])){continue;}
            $item = array_shift($map[$key]);
            $params = $params->filter(function($value)use($item){
                return !($value['logistic_number'] == $item['logistic_number'] && $value['sku'] == $item['sku'])  ;
            });
            $OPCCollect  = $OPCCollect->filter(function($opc)use($item){
                return !($opc['logistic_number'] == $item['logistic_number'] && $opc['sku'] == $item['sku'] && $opc['amount'] == $item['amount'] && $item['id'] == $opc['id']);
            });
            if($item['amount']!= $param['amount']){
                $param['id'] = $item['id'];
                $update->push($param);
            }
        }

        return $update;
    }

    public function 删选出删除的OrderPackageCommodities(&$OPCCollect,&$params)
    {
        $deleteIds = [];
        $map = [];
        if($OPCCollect == null){return $deleteIds;}
        foreach ($params as $item) {
            $key = ' logistic_number='.$item['logistic_number'].' sku='.$item['sku'].' amount='.$item['amount'];
            if(!isset($map[$key])){
                $map[$key] = [];
            }
            $map[$key][] = $item;
        }
        foreach ($OPCCollect as $opc) {
            $key = ' logistic_number='.$opc['logistic_number'].' sku='.$opc['sku'].' amount='.$opc['amount'];
            if(!isset($map[$key]) || count($map[$key])==0){
                $deleteIds[] = $opc['id'];
            }
        }

        return $deleteIds;
    }

    public function 删除OPC以及对应的追踪件($ids)
    {
        if(!$ids){return;}
        $OPCs = OrderPackageCommodities::query()->whereIn('id', $ids)->get();
        if($OPCs->count() == 0){return;}
        try {
            OrderPackageCommodities::query()->whereIn('id', $ids)->delete();
            app('LogService')->log(__METHOD__, __FUNCTION__, '删除OrderPackageCommodities ' . count($ids) . json_encode($OPCs));
            $orderTracking = OrderTracking::query()->whereIn('order_package_commodity_id',$ids)->get();
            app(OrderTrackingService::class)->deleteOrderTracings($orderTracking);
        } catch (\Exception $e) {
            app('LogService')->log(__METHOD__, __FUNCTION__, '删除OrderPackageCommodities ' . count($ids) . json_encode($OPCs).$e->getMessage().$e->getTraceAsString());
        }
    }

    public function 根据更新数组进行更新($updateParams)
    {
        if(!isset($updateParams)){return;}
        if(is_array($updateParams) && count($updateParams)==0){return;}
        $commodity_map = $this->返回Commodity数组_根据数组中sku($updateParams);
        $orderPackages_map = app(OrderPackageService::class)->返回OrderPackage数组_根据数组中的快递单号($updateParams);
        $dataTime = Carbon::now()->format('Y-m-d H:i:s');
        $update_params = [['id','commodity_id','order_package_id','amount','updated_at']];
        foreach ($updateParams as $updateParam) {
            $commodity_key = ' ownerCode='.($updateParam['ownerCode'] ?? '').' sku='.($updateParam['sku'] ?? '');
            $commodity = $commodity_map[$commodity_key] ?? '';
            $orderPackage = $orderPackages_map[$updateParam['logistic_number']] ?? '';
            $update_params[] = [
                'id' => $updateParam['id'],
                'commodity_id' => $commodity->id ?? '',
                'order_package_id' => $orderPackage->id ?? '',
                'amount' => $updateParam['amount'],
                'updated_at' => $dataTime
            ];
        }
        $this->batchUpdate($update_params);
    }

    private function 返回Commodity数组_根据数组中sku($params)
    {
        $skus = array_unique(data_get($params,'*.sku'));
        $commodities = Commodity::query()->with('owner')->whereIn('sku',$skus)->get();
        $commodity_map = [];
        foreach ($commodities as $commodity) {
            $key = ' ownerCode='.($commodity->owner->code ?? '').' sku='.$commodity->sku;
            $commodity_map[$key] = $commodity;
        }
        return $commodity_map;
    }

    // TODO
    public function deleteUnnecessaryOrderCommodities($ids)
    {
        if(!$ids)return;
        if(count($ids)==0)return;
        OrderPackageCommodities::query()->whereHas('package',function($query)use($ids){
            $query->whereIn('id',$ids);
        })->delete();
        app('LogService')->log(__METHOD__,__FUNCTION__,'删除 OrderPackageCommodities'.json_encode($ids));
    }
    // TODO
    public function syncOrderPackageCommodities(&$orderHeaders)
    {
        /**
         * @var DataHandlerService $dataHandService
         * @var CommodityService $commodityService
         * @var OrderPackageService $orderPackageService
         */
        $dataHandService = app('DataHandlerService');
        $commodityService = app('CommodityService');
        $orderPackageService  = app( 'OrderPackageService');
        if(!$orderHeaders)return ;

        $commodityService->getByWmsOrders($orderHeaders);   // 预先处理     3s
        $orderPackages = $orderPackageService->getByWmsOrders($orderHeaders);
        $orderCommodities = $this->getByWmsOrder($orderHeaders);

        $package_map = $dataHandService->dataHeader(['logistic_number'],$orderPackages);
        $orderCommodities = $this->regroupOrderCommodities($orderCommodities);

        $orderAllocationDetails = $this->regroupWmsOrderAllocationDetails($orderHeaders);
        $del_orderCommodities  =[];

        $update_params =$this->filterUpdateParams($orderAllocationDetails,$orderCommodities,$del_orderCommodities);                  // 修改
        $inner_params = $this->filterInnerParams($orderAllocationDetails,$orderCommodities);                              // 创建
        $delete_params = $this->filterDeleteParams($orderAllocationDetails,$orderCommodities);                                           // 删除

        if(count($inner_params)>0)
            $this->createOrderCommodities($inner_params,$package_map);  // 创建 3s

        if(count($update_params)>0)
            $this->updateOrderCommodities($update_params);              // 更新

        if(count($delete_params)>0)
            $this->deleteOrderCommodities($delete_params);              // 删除

        if(count($del_orderCommodities)>0)
            $this->deleteOrderCommodities($del_orderCommodities);       // 删除
    }
    // TODO 重组已有的OrderCommodities
    public function regroupOrderCommodities(&$orderCommodities)
    {
        $params = [];
        $orderCommodities->each(function($orderCommodity)use(&$params){
            $order_no = $orderCommodity->package->order->code ?? '';
            $logistic_number = $orderCommodity->package->logistic_number ?? '';
            $sku = $orderCommodity->commodity->sku ?? '';
            $key = ' orderno='.$order_no.' logsitic_number='.$logistic_number.' sku='.$sku.' ';
            $params[$key][] = [
                'id' =>$orderCommodity->id,
                'orderno'=>$order_no,
                'logistic_number'=>$logistic_number,
                'sku' => $sku,
                'amount' => $orderCommodity->amount,
                'order_package_id'=>$orderCommodity->package->id ?? '',
                'commodity_id'=>$orderCommodity->commodity->id ?? '',
            ];
        });
        return $params;
    }
    // TODO 重组OrderAllocationDetails
    public function regroupWmsOrderAllocationDetails(&$orderHeaders)
    {
        /**
         * @var OracleDOCOrderHeader $orderHeader
         */
        $params =[];
        foreach ($orderHeaders as $orderHeader) {
            $order_no = $orderHeader->orderno;
            $actAllocationDetails = $orderHeader->actAllocationDetails ?? [];
            $actAllocationDetails->each(function($item)use(&$params,$order_no){
                $logistic_number = $item->picktotraceid;
                $sku = $item->sku;
                $key = ' orderno='.$order_no.' logsitic_number='.$logistic_number.' sku='.$sku.' ';
                if(isset($params[$key])){
                    $params[$key]['amount']+= $item->qty_each;
                }else{
                    $params[$key] = [
                        'orderno'=>$item->orderno,
                        'logistic_number'=>$item->picktotraceid,
                        'sku' => $sku,
                        'amount' => $item->qty_each,
                        'owner_code' => $item->customerid
                    ];
                }
            });
        }
        return $params;
    }
    // TODO 过滤已有的
    public function filterUpdateParams(&$orderAllocationDetails,&$orderCommodities,&$del_orderCommodities)
    {
        $update_params = [];
        foreach ($orderCommodities as $key=>$orderCommodity) {
            if(isset($orderAllocationDetails[$key])){
                if(count($orderCommodity) == 1  && $orderAllocationDetails[$key]['amount'] != $orderCommodity[0]['amount']){
                    $update_params[$key] = $orderCommodity[0];
                    $update_params['amount'] = $orderAllocationDetails[$key]['amount'];
                }elseif(count($orderCommodity)>1){
                    $update_params[$key] = array_shift($orderCommodity);
                    $update_params[$key]['amount'] = $orderAllocationDetails[$key]['amount'];
                    collect($orderCommodity)->each(function($item)use(&$del_orderCommodities){
                        $del_orderCommodities[] = $item;
                    });
                }
                unset($orderCommodities[$key],$orderAllocationDetails[$key]);
            }
        }
        return $update_params;
    }
    // TODO 创建
    public function filterInnerParams(&$orderAllocationDetails,&$orderCommodities)
    {
        $inner_params = [];
        foreach ($orderAllocationDetails as $key=>$orderAllocationDetail) {
            if(!($orderCommodities[$key] ?? false)){
                $inner_params[] = $orderAllocationDetail;
                unset($orderCommodities[$key],$orderAllocationDetail);
            }
        }
        return $inner_params;
    }
    // TODO 更新
//    public function filterUpdateParams(&$orderAllocationDetails,&$orderCommodities)
//    {
//        $update_params = [];
//        foreach ($orderCommodities as $key => $orderCommodity) {
//            if(isset($orderAllocationDetails[$key])){
//                if($orderCommodity->amount != $orderAllocationDetails[$key]->amount){
//                    $update_params[$key] = $orderCommodity[$key]->amount = $orderAllocationDetails[$key]->amount;
//                    unset($orderCommodity,$orderAllocationDetails[$key]);
//                }
//            }
//        }
//        return $update_params;
//    }
    // TODO
    public function filterDeleteParams(&$orderAllocationDetails,&$orderCommodities)
    {
        $del_params = [];
        foreach ($orderCommodities as $key => $orderCommodity) {
            if(!isset($orderAllocationDetails[$key])){
                collect($orderCommodity)->each(function ($item)use(&$del_params){
                    $del_params[] = $item;
                });
                unset($orderCommodities[$key]);
            }
        }
        return $del_params;
    }
    // TODO  根据数据创建
    public function createOrderCommodities($inner_params,$package_map)
    {
        /** @var DataHandlerService $dataHandlerService */
        $dataHandlerService  = app('DataHandlerService');
        $sku = [];$owners = [];
        foreach ($inner_params as $inner_param) {
            $sku_code = $inner_param['sku'];$owner_code = $inner_param['owner_code'];
            if(!isset($sku[$sku_code]))
                $sku[$sku_code] = $sku_code;
            if(!isset($owner_code[$owner_code]))
                $owners[$owner_code] = $owner_code;
        }
        $commodities = Commodity::query()->with('owner')->whereHas('owner',function ($query)use($owners){
            $query->whereIn('code',$owners);
        })->whereIn('sku',$sku)->get();
        $commodity_map = [];
        foreach ($commodities as $commodity) {
            $key = ' owner='.$commodity->owner->code.' sku='.$commodity->sku;
            $commodity_map[$key] = $commodity;
        }
        $create_params =[];
        $date = Carbon::now();
        foreach ($inner_params as $inner_param) {
            if($inner_param['logistic_number'] === '*' || $inner_param['logistic_number'] === ' ')continue;
            $package = $dataHandlerService->getKeyValue(['logistic_number'=>$inner_param['logistic_number']],$package_map);
            if(!$package)continue;
            $commodity = $commodity_map[' owner='.$inner_param['owner_code'].' sku='.$inner_param['sku']] ?? null;
            $create_params[] = [
                'order_package_id'=>$package->id,
                'commodity_id'=>$commodity->id ?? null,
                'amount' => $inner_param['amount'],
                'created_at' => $date,
                'updated_at' => $date
            ];
        }
        if(count($create_params)>0){
            try {
                $inner_array = array_chunk($create_params,1000);
                foreach ($inner_array as $item) {
                    $bool = $this->insert($item);
                    LogService::log(__METHOD__,__FUNCTION__,'批量添加 orderCommodity --'. $bool ." || ".count($create_params).' || '.json_encode($create_params));
                }
            } catch (\Exception $e) {
                LogService::log(__METHOD__,__FUNCTION__.'error','批量添加 orderCommodity error'." || ".count($create_params).' || '.json_encode($create_params));
            }
        }
    }
    // TODO
    public function updateOrderCommodities($orderCommodities)
    {
        if(!$orderCommodities)return ;
        $updated_at = Carbon::now();
        $update_params = [['id','order_package_id','commodity_id','amount','updated_at']];
        foreach ($orderCommodities as $orderCommodity) {
            $update_params[] = [
                'id' => $orderCommodity['id'] ?? '',
                'order_package_id'=>$orderCommodity['order_package_id'] ?? '',
                'commodity_id'=>$orderCommodity['commodity_id'] ?? '',
                'amount' => $orderCommodity['amount'],
                'updated_at' => $updated_at
            ];
        }
        if(count($update_params)>1)
            $this->batchUpdate($update_params);
    }
    // TODO 删除
    public function deleteOrderCommodities($orderCommodities){
        if(!$orderCommodities)return;
        if(count($orderCommodities)==0)return;
        try {
            $ids = data_get($orderCommodities, '*.id');
            if(count($ids) >0){
                $bool = OrderPackageCommodities::query()->whereIn('id', data_get($orderCommodities, '*.id'))->delete();
                LogService::log(__METHOD__, __FUNCTION__, '批量删除 OrderCommodity -- ' . $bool . '||' .count($orderCommodities)  . ' || ' . json_encode($orderCommodities));
            }
        } catch (\Exception $e) {
            LogService::log(__METHOD__, __FUNCTION__.' error', '批量删除 OrderCommodity Error-- ' . $e->getMessage() . '||' . $e->getTraceAsString() );
        }

    }
}
