Browse Source

Merge branch 'master' into zengjun

# Conflicts:
#	app/Http/Controllers/TestController.php
ajun 4 năm trước cách đây
mục cha
commit
c7003f2efd

+ 1 - 1
app/Console/Kernel.php

@@ -82,7 +82,7 @@ class  Kernel extends ConsoleKernel
         $schedule->command('createProcurementTotalBill')->monthlyOn(1);
         $schedule->command('orderCountingRecordTask')->dailyAt("1:00");
         //$schedule->command('check:cacheRack')->everyMinute();
-        $schedule->command('AccordingToOwnersManualBack')->everyThirtyMinutes();
+        $schedule->command('AccordingToOwnersManualBack')->everyThirtyMinutes()->between('9:00','16:30');
     }
 
     /**

+ 18 - 18
app/Filters/OrderPackageFilters.php

@@ -18,24 +18,24 @@ class OrderPackageFilters
     protected $request;
     protected $queryBuilder;
     protected $filters = [
-        'logistic_number',
-        'status',
-        'received_at_start',
-        'default_logistics',
-        'is_issue',
-        'sync_routes_flag',
-        'remark',
-        'received_at_end',
-        'is_weighed',
-        'logistic',
-        'owner',
-        'sent_at_start',
-        'sent_at_end',
-        'default_date',
-        'has_transfer_status',
-        'is_new_rejecting',
-        'result_explain',
-        'issue_type_name',
+        'logistic_number',//快递单号
+        'status',//状态
+        'received_at_start',//签收时间开始
+        'default_logistics',//是否默认承运商
+        'is_issue',//是否为问题件
+        'sync_routes_flag',//是否同步过路由
+        'remark',//备注
+        'received_at_end',//签收时间截止
+        'is_weighed',//是否称重
+        'logistic',//承运商
+        'owner',//货主
+        'sent_at_start',//复核时间开始
+        'sent_at_end',//复核时间截止
+        'default_date',//默认日期
+        'has_transfer_status',//是否有路由信息
+        'is_new_rejecting',//退件状态
+        'result_explain',//情况说明
+        'issue_type_name',//问题件类型
         'order_notes',//订单备注
         'exception_status',//订单备注
         'is_customer_service_remark',//是否有客服备注

+ 178 - 0
app/Http/Controllers/StoreOutReviewController.php

@@ -0,0 +1,178 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\DB;
+
+class StoreOutReviewController extends Controller
+{
+    public function index(Request $request)
+    {
+        return view("storeOut.storeOutReview.index");
+    }
+
+
+    public function apiGetOrderDetail(Request $request)
+    {
+        $orderno = $request->input('orderno');
+        $orderDetail = DB::connection("oracle")->select(
+            "
+            SELECT
+        rtrim( 'ACT_ALLOCATION_DETAILS.SKU=' || cast( act_allocation_details.SKU AS VARCHAR2 ( 100 ) ) ) || ',' || rtrim( 'ACT_ALLOCATION_DETAILS.ALLOCATIONDETAILSID=' || cast( act_allocation_details.ALLOCATIONDETAILSID AS VARCHAR2 ( 100 ) ) ) PKEY,
+        act_allocation_details.OrderNo,
+        act_allocation_details.Orderlineno,
+        act_allocation_details.skulineno,
+        act_allocation_details.customerId,
+        act_allocation_details.SKU,
+        bas_sku.DESCR_C SKUDESCRC,
+        bas_sku.DESCR_E SKUDESCRE,
+        doc_order_header.ROUTE,
+        DOC_Order_Details.ERPCancelFlag,
+        act_allocation_details.PACKID,
+        b1.descr UOM_EACH_NAME,
+        act_allocation_details.Palletize,
+        doc_order_header.notes AS ORDERNOTES,
+        doc_order_header.CarrierID,
+        doc_order_header.OrderType,
+        rdc.CartonGroup AS CARTONGROUP1,
+        act_allocation_details.PICKTOTRACEID,
+        act_allocation_details.LOCATION,
+        act_allocation_details.AllocationDetailsID,
+        bas_sku.SerialNoCatch,
+        bas_sku.OutboundSerialNoQtyControl,
+        bas_sku.SecondSerialNoCatch,
+        bas_sku.CHK_SCN_UOM,
+        bas_sku.ScanWhenCasePicking,
+        bas_sku.SCANWHENCHECK,
+        bas_sku.SKU_Group1,
+        bas_sku.GROSSWEIGHT,
+        bas_sku.ScanWhenReceive,
+        bas_sku.ScanWhenPutaway,
+        bcf.SerialNo_RuleID,
+        bcf.SubSerialNo_RuleID,
+        bcf.SN_BCH,
+        bcf.SN_INC,
+        doc_order_header.SerialNoCatch AS ORDERSERIALNOCATCH,
+        doc_order_header.InvoicePrintFlag,
+        doc_order_header.OrderHandleInstruction,
+        doc_order_header.CartonGroup AS CARTONGROUPORDERHEADER,
+        doc_order_header.CartonID AS CARTONIDORDERHEADER,
+        act_allocation_details.LOTNUM,
+        act_allocation_details.qty_each AS QTY,
+        act_allocation_details.LOTNUM,
+        act_allocation_details.qty_each AS UNCHECKQTY,
+        act_allocation_details.notes,
+        bas_sku.CARTONGROUP,
+        act_allocation_details.status,
+        c5.CODENAME_C AS ROUTE_NAME,
+        c.CODENAME_C AS STATUS_NAME,
+        bas_sku.ALTERNATE_SKU1,
+        bas_sku.ALTERNATE_SKU2,
+        bas_sku.ALTERNATE_SKU3,
+        bas_sku.ALTERNATE_SKU4,
+        bas_sku.ALTERNATE_SKU5,
+        act_allocation_details.PACKFLAG,
+        bas_sku.ImageAddress,
+        bas_sku.cube,
+        '' AS SKU_LABEL,
+        SUM( CASE WHEN act_allocation_details.PackFlag = 'Y' THEN act_allocation_details.Qty_Each ELSE 0 END ) over ( partition BY act_allocation_details.orderno ) AS PACKEDQTY,
+        SUM( CASE WHEN act_allocation_details.PackFlag = 'Y' THEN 0 ELSE act_allocation_details.Qty_Each END ) over ( partition BY act_allocation_details.orderno ) AS UNPACKQTY,
+        SUM( CASE WHEN act_allocation_details.PackFlag = 'Y' THEN 0 ELSE act_allocation_details.Cubic END ) over ( partition BY act_allocation_details.orderno ) AS TOTALCUBIC,
+        INV_LOT_ATT.QCREPORTFILENAME AS QCREPORTFILENAME,
+        INV_LOT_ATT.LotAtt01 AS LotAtt01,
+        INV_LOT_ATT.LotAtt02 AS LotAtt02,
+        INV_LOT_ATT.LotAtt03 AS LotAtt03,
+        INV_LOT_ATT.LotAtt04 AS LotAtt04,
+        INV_LOT_ATT.LotAtt05 AS LotAtt05,
+        INV_LOT_ATT.LotAtt06 AS LotAtt06,
+        INV_LOT_ATT.LotAtt07 AS LotAtt07,
+        INV_LOT_ATT.LotAtt08 AS LotAtt08,
+        INV_LOT_ATT.LotAtt09 AS LotAtt09,
+        INV_LOT_ATT.LotAtt10 AS LotAtt10,
+        INV_LOT_ATT.LotAtt11 AS LotAtt11,
+        INV_LOT_ATT.LotAtt12 AS LotAtt12,
+        doc_order_header.CONSIGNEEID,
+        doc_order_header.CONSIGNEENAME CONSIGNEEID_NAME,
+        BAS_Customer.IMAGEADDRESS AS CONSIGNEEIMAGEADDRESS,
+        act_allocation_details.uom,
+        doc_order_header.CustomerID,
+        BAS_Customer_OW.Descr_C AS CUSTOMERID_NAME,
+        doc_order_header.CONSIGNEENAME AS CONSIGNEENAME,
+        doc_order_header.C_Address1 AS C_ADDRESS1,
+        doc_order_header.C_Contact AS CONSIGNEECONTACT,
+        doc_order_header.C_Tel1 AS CONSIGNEETEL1,
+        doc_order_header.SOREFERENCE1,
+        doc_order_header.SOREFERENCE2,
+        doc_order_header.SOREFERENCE3,
+        doc_order_header.SOREFERENCE4,
+        doc_order_header.SOREFERENCE5,
+        BAS_Customer_OW.SKUANALYSISFIELDS,
+        bas_sku.LotID,
+        DOC_Order_Details.FreeGift,
+        doc_order_header.Warehouseid,
+        doc_order_header.waveNo,
+        act_allocation_details.pickedWho,
+        TO_CHAR( act_allocation_details.pickedtime, 'yyyy-MM-dd HH24:MI' ) AS PICKEDTIME,
+        BAS_Location.WorkingArea
+FROM
+    ACT_Allocation_Details act_allocation_details
+        LEFT JOIN BAS_SKU bas_sku ON bas_sku.SKU = act_allocation_details.SKU
+        AND bas_sku.CUSTOMERID = act_allocation_details.CUSTOMERID
+        LEFT JOIN INV_LOT_ATT INV_LOT_ATT ON INV_LOT_ATT.LOTNUM = act_allocation_details.LOTNUM
+        LEFT JOIN view_cod_so_sts c ON act_allocation_details.status = c.code
+        LEFT JOIN doc_order_header doc_order_header ON doc_order_header.OrderNo = act_allocation_details.OrderNo
+        LEFT JOIN DOC_Order_Details DOC_Order_Details ON act_allocation_details.OrderNo = DOC_Order_Details.OrderNo
+        AND act_allocation_details.OrderLineNo = DOC_Order_Details.OrderLineNo
+        LEFT JOIN BAS_Customer BAS_Customer ON doc_order_header.CONSIGNEEID = BAS_Customer.CustomerID
+        AND BAS_Customer.Customer_Type = 'CO'
+        LEFT JOIN BAS_Customer BAS_Customer_OW ON doc_order_header.CustomerID = BAS_Customer_OW.CustomerID
+        AND BAS_Customer_OW.Customer_Type = 'OW'
+        LEFT JOIN VIEW_COD_ROU_COD c5 ON doc_order_header.ROUTE = c5.code
+        LEFT JOIN view_uom b1 ON b1.uom = 'EA'
+        AND act_allocation_details.packid = b1.packid
+        LEFT JOIN BAS_CustomerFreight bcf ON bas_sku.customerid = bcf.customerid
+        AND bas_sku.FreightClass = bcf.FreightCode
+        LEFT JOIN RUL_Delivery_Config rdc ON doc_order_header.Warehouseid = rdc.WarehouseID
+        AND doc_order_header.CustomerID = rdc.CustomerID
+        AND doc_order_header.CarrierID = rdc.CarrierID
+        LEFT JOIN BAS_Location BAS_Location ON act_allocation_details.Location = BAS_Location.locationId
+WHERE
+        1 = 1
+  AND ( act_allocation_details.Status >= '40' AND act_allocation_details.Status <= '60' )   --分配完成 | 部分拣货 |拣货完成
+  AND act_allocation_details.ORDERNO = ?
+  AND act_allocation_details.PackFlag <> 'Y'
+ORDER BY
+    act_allocation_details.PACKFLAG,
+    act_allocation_details.status DESC,
+    act_allocation_details.sku,
+    act_allocation_details.ALLOCATIONDETAILSID
+", [$orderno]);
+        return ['success' => true, 'data' => $orderDetail];
+    }
+
+    public function review(Request $request)
+    {
+        DB::transaction(function ($request) {
+            //普通复核的长宽高由WAS回写
+            //               ('202108160001','SO21081000004','',1.00000,3,0,0,0,1.00000,sysdate,'liutengfei',sysdate,'liutengfei')
+            $TRACEID = $request->input('traceid');
+            $ORDERNO = $request->input('orderno');
+            $CARTONGROUP = '';
+            $GROSSWEIGHT = $request->input('grossweight');//总重
+            $QTY = $request->input('qty');//数量
+            $LENGTH = 0;
+            $WIDTH = 0;
+            $HEIGHT = 0;
+            $STANDARDWEIGHT = $request->input('standardweight');
+            $ADDTIME = now()->toDateTimeString();
+            $ADDWHO = auth()->user()->name;
+            $EDITTIME = now()->toDateTimeString();
+            $EDITWHO = auth()->user()->name;
+            DB::insert("
+        INSERT INTO DOC_Order_Packing_Summary
+            (TRACEID,ORDERNO,CARTONGROUP,GROSSWEIGHT,QTY,LENGTH,WIDTH,HEIGHT,STANDARDWEIGHT,ADDTIME,ADDWHO,EDITTIME,EDITWHO)
+        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)", [$TRACEID, $ORDERNO, $CARTONGROUP, $GROSSWEIGHT, $QTY, $LENGTH, $WIDTH, $HEIGHT, $STANDARDWEIGHT, $ADDTIME, $ADDWHO, $EDITTIME, $EDITWHO,]);
+        });
+    }
+}

+ 50 - 74
app/Http/Controllers/TestController.php

@@ -45,12 +45,14 @@ use App\Services\BatchService;
 use App\Services\CacheShelfService;
 use App\Services\ForeignHaiRoboticsService;
 use App\Services\OrderPackageReceivedSyncService;
+use App\Services\OrderPackageService;
 use App\Services\OrderService;
 use App\Services\OwnerFeeTotalService;
 use App\Services\OwnerLogisticFeeReportService;
 use App\Services\OwnerPriceOperationService;
 use App\Services\OwnerStoreFeeReportService;
 use App\Services\OwnerStoreOutFeeReportService;
+use App\Services\ReviewService;
 use App\Services\StationService;
 use App\Services\StorageService;
 use App\Station;
@@ -103,73 +105,10 @@ class TestController extends Controller
         return call_user_func([$this, $method], $request);
     }
 
-    private function valFormat($val):?string
+    public function test()
     {
-        if ($val!==null){
-            $ret = date("Y-m-d H:i:s",strtotime($val))===(string)$val;
-            if ($ret)$val = "to_date('".$val."','yyyy-mm-dd hh24:mi:ss')";
-            else $val = "'".$val."'";
-        }else $val = "null";
-        return $val;
-    }
 
-    public function test1($task,$amount){
-        DB::connection("oracle")->beginTransaction();
-        try {
-            $columns = '';
-            $values = '';
-            foreach ($task as $key => $val) {
-                if (Str::upper($key) == 'TASKID_SEQUENCE') {
-                    $taskMax = DB::connection("oracle")->selectOne(DB::raw("select MAX(TASKID_SEQUENCE) maxseq from TSK_TASKLISTS where taskid = ?"), [$task->taskid]);
-                    $val = $taskMax->maxseq + 1;
-                }
-                if (Str::upper($key) == 'FMQTY' || Str::upper($key) == 'FMQTY_EACH'
-                    || Str::upper($key) == 'PLANTOQTY' || Str::upper($key) == 'PLANTOQTY_EACH') {
-                    $val -= $amount;
-                    $task->$key = $amount;
-                }
-                $columns .= $key . ",";
-                $values .= $this->valFormat($val) . ",";
-            }
-            $columns = mb_substr($columns, 0, -1);
-            $values = mb_substr($values, 0, -1);
-            $sql = <<<sql
-    INSERT INTO TSK_TASKLISTS({$columns}) VALUES({$values})
-sql;
-            dd($sql);
-        } catch (\Exception $e) {
-            dd($e);
-        }
-    }
 
-    public function test()
-    {
-        $a = "2021-09-13 00:00:00";
-        dd(mb_substr($a,0,10));
-        $models = app("MaterialBoxModelService")->getModelSortedByOwner(null);
-        foreach ($models as $model){
-            $box = app("MaterialBoxService")->getAnEmptyBox($model,[],2);
-            dd($box);
-            if ($box)return $box;
-        }
-        dd();
-        TaskTransaction::query()->where("id",">=",280)->delete();
-        /*$a= new StorageService();
-        $a->clearTask(["HAIB1-01-01"]);
-        $task = StationTaskMaterialBox::query()->find(90233);
-        $station = Station::query()->find(11);
-        $foreignHaiRoboticsService = new ForeignHaiRoboticsService();
-        $foreignHaiRoboticsService->putBinToStore_fromCacheShelf($task, $station);
-        dd(1);*/
-        /*$batchService = new BatchService();
-        $batches = Batch::query()->where("id",171829)->get();
-        $batchService->assignTasks($batches);
-        dd();*/
-        /*TaskTransaction::query()->where("id",">=",277)->delete();
-        StationTaskMaterialBox::query()->whereIn("id",[89685,89686,89687])->delete();
-        app("CacheShelfService")->_stationCacheLightOff("HAIB1-01-01");//灭灯
-        app("CacheShelfService")->_stationCacheLightOff("HAIB1-02-01");//灭灯
-        dd(1);*/
         Station::query()->where("station_type_id", 5)->update(["status" => 1]);
         Cache::forget("CACHE_SHELF_AVAILABLE");
         $station = ["HAIB1-01-01", "HAIB1-02-01"];
@@ -364,26 +303,28 @@ sql;
             ]);
     }
 
-    public function syncOrderPackage(){
-        ini_set('memory_limit','500M');
+    public function syncOrderPackage()
+    {
+        ini_set('memory_limit', '500M');
         ini_set('max_execution_time', 0);
         $orderPackingSummary = OracleDocOrderPackingSummary::query()
-            ->where('editTime','>=','2021-09-11 12:00:00')
-            ->where('editTime','<=','2021-09-12 12:40:00')
+            ->where('editTime', '>=', '2021-09-11 12:00:00')
+            ->where('editTime', '<=', '2021-09-12 12:40:00')
             ->get();
 
         $orderPackingSummary_chunk = $orderPackingSummary->chunk(200);
         foreach ($orderPackingSummary_chunk as $orderPackingSummarys) {
             foreach ($orderPackingSummarys as $orderPackingSummary) {
+                $orderPackage = OrderPackage::query()->where('logistic_number', $orderPackingSummary->traceid)->first();
                 $orderPackage = OrderPackage::query()->where('logistic_number',$orderPackingSummary->traceid)->first();
                 if (!$orderPackage)continue;
                 $orderPackage->update([
-                    'uploaded_to_wms'=> true,
-                    'weight'=>$orderPackingSummary->grossweight,
-                    'length'=>$orderPackingSummary->length,
-                    'width'=>$orderPackingSummary->width,
-                    'height'=>$orderPackingSummary->height,
-                    'weighed_at'=>$orderPackingSummary->edittime
+                    'uploaded_to_wms' => true,
+                    'weight' => $orderPackingSummary->grossweight,
+                    'length' => $orderPackingSummary->length,
+                    'width' => $orderPackingSummary->width,
+                    'height' => $orderPackingSummary->height,
+                    'weighed_at' => $orderPackingSummary->edittime
                 ]);
                 dispatch(new WeightUpdateInstantBill($orderPackage));
             }
@@ -391,4 +332,39 @@ sql;
         return ['success' => true];
     }
 
+    public function collectUpload()
+    {
+        /** @var OrderPackageService $service */
+        $service = app('OrderPackageService');
+        return $service->collectUpload([
+            '75803656098638',
+            '75803656098612'
+        ]);
+    }
+
+    public function init_在途异常()
+    {
+//        $logistic_numbers = OrderPackage::query()
+//            ->select('logistic_number')
+//            ->where('exception_status', 5)
+//            ->where('created_at', '>=', now()->subDays(20)->toDateTimeString())
+//            ->pluck('logistic_number');
+//
+        /** @var OrderPackageReceivedSyncService $service */
+        $service = app('OrderPackageReceivedSyncService');
+//        $service->syncLogisticRoute(false, $logistic_numbers);
+
+
+        $logistic_numbers = OrderPackage::query()
+            ->select(['logistic_number', 'order_id', 'id'])
+            ->whereIn('order_id', function ($query) {
+                $query->from('orders')->selectRaw('id')->whereIn('logistic_id', function ($builder) {
+                    $builder->from('logistics')->selectRaw('id')->where('type', '=', '快递')->whereNotIn('belong_company', ['顺丰', '中通', '韵达', '圆通', '京东']);
+                });
+            })
+            ->where('exception_status', 5)
+            ->where('created_at', '>=', now()->subDays(20)->toDateTimeString())
+            ->pluck('logistic_number');
+        $service->syncLogisticRouteByAliJiSu($logistic_numbers);
+    }
 }

+ 4 - 4
app/Jobs/LogisticZopSync.php

@@ -24,7 +24,7 @@ class LogisticZopSync implements ShouldQueue
      * @var string $logistic_number
      */
     protected $logistic_number;
-     /**@var LogisticZopService $logistic_zop_service **/
+    /**@var LogisticZopService $logistic_zop_service * */
     protected $logistic_zop_service;
     /**
      * @var  OrderPackageReceivedSyncService $order_package_received_sync_service
@@ -52,9 +52,9 @@ class LogisticZopSync implements ShouldQueue
     {
         LogService::log(LogisticZopSync::class, "JOB-ZOP", $this->logistic_number);
         //标记上有同步的操作
-        OrderPackage::query()->where('logistic_number', $this->logistic_number)->update(['sync_routes_flag'=> true]);
+        OrderPackage::query()->where('logistic_number', $this->logistic_number)->update(['sync_routes_flag' => true]);
         $nativeResponse = $this->logistic_zop_service->query($this->logistic_number);
-        $logisticResponseFormatted = $this->logistic_zop_service->format($nativeResponse,$this->logistic_number);
-        $this->order_package_received_sync_service->update([$logisticResponseFormatted]);
+        $logisticResponseFormatted = $this->logistic_zop_service->format($nativeResponse, $this->logistic_number);
+        if (!empty($logisticResponseFormatted)) $this->order_package_received_sync_service->update([$logisticResponseFormatted]);
     }
 }

+ 18 - 0
app/OracleDOCOrderPackings.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class OracleDOCOrderPackings extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    protected $connection="oracle";
+    protected $table="DOC_Order_Packing";
+    public $timestamps=false;
+}

+ 0 - 4
app/OrderPackage.php

@@ -3,8 +3,6 @@
 namespace App;
 
 use App\Http\Controllers\Controller;
-use App\Services\LogService;
-use App\Services\OrderPackageService;
 use App\Services\OrderService;
 use App\Traits\ModelTimeFormat;
 use Carbon\Carbon;
@@ -16,8 +14,6 @@ use Illuminate\Support\Arr;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 
-use App\Traits\ModelLogChanging;
-
 class OrderPackage extends Model
 {
 //    use ModelLogChanging;

+ 2 - 0
app/Providers/AppServiceProvider.php

@@ -85,6 +85,7 @@ use App\Services\ProvinceService;
 use App\Services\RealtimePendingOrdersService;
 use App\Services\RejectedBillItemService;
 use App\Services\RejectedBillService;
+use App\Services\ReviewService;
 use App\Services\ShopService;
 use App\Services\RejectedService;
 use App\Services\StationRuleBatchService;
@@ -209,6 +210,7 @@ class AppServiceProvider extends ServiceProvider
     }
 
     private function loadingService(){
+        app()->singleton('ReviewService',ReviewService::class);
         app()->singleton('AllInventoryService',AllInventoryService::class);
         app()->singleton('AuthorityService',AuthorityService::class);
         app()->singleton('BatchService',BatchService::class);

+ 3 - 0
app/Services/LogisticZopService.php

@@ -32,6 +32,9 @@ class LogisticZopService implements LogisticRouteInterface
     {
 
         $order_package = OrderPackage::query()->where('logistic_number', $logistic_number)->first();
+        if (empty($order_package)) {
+            return [];
+        }
         $result = [
             'logistic_number' => $logistic_number,
             'status' => $order_package->status,

+ 16 - 0
app/Services/MaterialBoxService.php

@@ -164,4 +164,20 @@ sql;
         }
         return array(rtrim($boxCodes,","),$map);
     }
+
+    /**
+     * 检查料箱规范
+     *
+     * @param string|null $code
+     *
+     * @return bool
+     */
+    public function checkBoxNorm(?string $code):bool
+    {
+        if (!$code)return false;
+        foreach (config("haiRou.box.prefix") as $prefix){
+            if (substr($code,0,strlen($prefix))==$prefix)return true;
+        }
+        return false;
+    }
 }

+ 19 - 13
app/Services/OrderPackageReceivedSyncService.php

@@ -27,7 +27,7 @@ class OrderPackageReceivedSyncService
      * 2 如果当前时间小于等于初始化时间,执行初始化脚本,将数据库中全部小于等于初始化时间的数据更新
      * @throws Exception
      */
-    public function syncLogisticRoute($is_to_init = false,$logistic_numbers = [])
+    public function syncLogisticRoute($is_to_init = false, $logistic_numbers = [])
     {
         ini_set('max_execution_time', 2 * 60 * 60);
         ini_set('memory_limit', '1024M');
@@ -97,18 +97,24 @@ class OrderPackageReceivedSyncService
         });
     }
 
-    public function syncLogisticRouteByAliJiSu()
+    public function syncLogisticRouteByAliJiSu($logistic_numbers = [])
     {
-        ini_set('max_execution_time', 2 * 60 * 60);
-        $query = OrderPackage::query()
-            ->select(['logistic_number', 'order_id', 'id'])
-            ->whereIn('order_id', function ($query) {
-                $query->from('orders')->selectRaw('id')->whereIn('logistic_id', function ($builder) {
-                    $builder->from('logistics')->selectRaw('id')->where('type', '=', '快递')->whereNotIn('belong_company', ['顺丰', '中通', '韵达', '圆通', '京东']);
+        if (empty($logistic_numbers)) {
+            ini_set('max_execution_time', 2 * 60 * 60);
+            $query = OrderPackage::query()
+                ->select(['logistic_number', 'order_id', 'id'])
+                ->whereIn('order_id', function ($query) {
+                    $query->from('orders')->selectRaw('id')->whereIn('logistic_id', function ($builder) {
+                        $builder->from('logistics')->selectRaw('id')->where('type', '=', '快递')->whereNotIn('belong_company', ['顺丰', '中通', '韵达', '圆通', '京东']);
+                    });
                 });
-            });
-        $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days')))
-            ->whereNull('received_at');
+            $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days')))
+                ->whereNull('received_at');
+        } else {
+            $query = OrderPackage::query()
+                ->select(['logistic_number', 'order_id', 'id'])
+                ->whereIn('logistic_number', $logistic_numbers);
+        }
 
         $query->chunkById(200, function ($orderPackages) {
             //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-阿里公用接口", json_encode($orderPackages));
@@ -201,12 +207,12 @@ class OrderPackageReceivedSyncService
             }
             //标记为手动更新的 status不更新
             if ($orderPackage->is_manual_update) {
-                if (OrderPackage::switchStatus($orderPackage->status)>OrderPackage::switchStatus($logisticResponse['status']??'生成订单')) {
+                if (OrderPackage::switchStatus($orderPackage->status) > OrderPackage::switchStatus($logisticResponse['status'] ?? '生成订单')) {
                     unset($logisticResponse['status']);
                 }
             }
             $logisticResponse = $this->setExceptionStatus($logisticResponse);
-            if (Str::contains($orderPackage->logistic_number,['SO','#','-'])) {
+            if (Str::contains($orderPackage->logistic_number, ['SO', '#', '-'])) {
                 $logisticResponse['exception_status'] = '单号异常';
             }
             if (isset($logisticResponse['exception_status'])) $logisticResponse['exception_status'] = OrderPackage::switchExceptionStatus($logisticResponse['exception_status']);

+ 168 - 83
app/Services/OrderPackageService.php

@@ -11,14 +11,18 @@ use App\Services\common\DataHandlerService;
 use Carbon\Carbon;
 use App\Traits\ServiceAppAop;
 use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\Http;
 
 
 class OrderPackageService
 {
     use ServiceAppAop;
-    protected $modelClass=OrderPackage::class;
-    public function batchUpdate(array $params){
-        return app(BatchUpdateService::class)->batchUpdate('order_packages',$params);
+
+    protected $modelClass = OrderPackage::class;
+
+    public function batchUpdate(array $params)
+    {
+        return app(BatchUpdateService::class)->batchUpdate('order_packages', $params);
     }
 
     /** @var OrderTrackingService $orderTrackingService */
@@ -29,10 +33,11 @@ class OrderPackageService
      * @param array $values
      * @return OrderPackage $package
      */
-    public function firstOrCreate($logistic_number, array $values){
-        /** @var $package OrderPackage  */
-        $package = OrderPackage::query()->where('logistic_number',$logistic_number)->first();
-        if ($package)return $package;
+    public function firstOrCreate($logistic_number, array $values)
+    {
+        /** @var $package OrderPackage */
+        $package = OrderPackage::query()->where('logistic_number', $logistic_number)->first();
+        if ($package) return $package;
 
         /** @var OrderService */
         $order = app('OrderService')->logisticNumberFirstOrCreateOrder($logistic_number);
@@ -59,47 +64,50 @@ class OrderPackageService
             ->paginate($paginate);
     }
 
-    public function getByWmsOrders($orderHeaders){
-        $order_nos = data_get($orderHeaders,'*.orderno');
+    public function getByWmsOrders($orderHeaders)
+    {
+        $order_nos = data_get($orderHeaders, '*.orderno');
         return OrderPackage::query()->with('order')
-            ->whereIn('order_id',function($query) use ($order_nos){
-                $query->from('orders')->select('id')->whereIn('code',$order_nos);
+            ->whereIn('order_id', function ($query) use ($order_nos) {
+                $query->from('orders')->select('id')->whereIn('code', $order_nos);
             })->get();
     }
 
     public function create(array $params)
     {
-        if(count($params) == 0)return null;
+        if (count($params) == 0) return null;
         try {
             $this->insert($params);
-            app('LogService')->log(__METHOD__,__FUNCTION__,'批量生成 orderPackage' . count($params) . json_encode($params));
+            app('LogService')->log(__METHOD__, __FUNCTION__, '批量生成 orderPackage' . count($params) . json_encode($params));
         } catch (\Exception $e) {
-            app('LogService')->log(__METHOD__,__FUNCTION__,'批量生成 orderPackage error ' . json_encode($params) . $e->getMessage() . $e->getTraceAsString());
+            app('LogService')->log(__METHOD__, __FUNCTION__, '批量生成 orderPackage error ' . json_encode($params) . $e->getMessage() . $e->getTraceAsString());
         } finally {
-            $logistic_numbers = data_get($params,'*.logistic_number');
+            $logistic_numbers = data_get($params, '*.logistic_number');
             unset($params);
-            return OrderPackage::query()->whereIn('logistic_number',$logistic_numbers)->get();
+            return OrderPackage::query()->whereIn('logistic_number', $logistic_numbers)->get();
         }
     }
 
     public function getByOrderNos($orderNos)
     {
         return OrderPackage::query()->with('order')
-            ->whereIn('order_id',function($query)use($orderNos){
-                $query->from('orders')->select('id')->whereIn('code',$orderNos);
+            ->whereIn('order_id', function ($query) use ($orderNos) {
+                $query->from('orders')->select('id')->whereIn('code', $orderNos);
             })->get();
     }
 
-    public function update($orderClientNo,$logisticNumber)
+    public function update($orderClientNo, $logisticNumber)
     {
-        $order = Order::query()->with('packages.commodities.commodity')->where('client_code',$orderClientNo)->first();
-        if(!$order){
-            $order = Order::query()->create(['client_code'=>$orderClientNo]);
+        $order = Order::query()->with('packages.commodities.commodity')->where('client_code', $orderClientNo)->first();
+        if (!$order) {
+            $order = Order::query()->create(['client_code' => $orderClientNo]);
+        }
+        $orderPackage = OrderPackage::query()->where('logistic_number', $logisticNumber)->first();
+        if ($orderPackage) {
+            return compact('orderPackage', 'order');
         }
-        $orderPackage = OrderPackage::query()->where('logistic_number',$logisticNumber)->first();
-        if($orderPackage){return  compact('orderPackage','order');}
-        $orderPackage = OrderPackage::query()->create(['order_id'=>$order->id,'logistic_number'=>$logisticNumber]);
-        return  compact('orderPackage','order');
+        $orderPackage = OrderPackage::query()->create(['order_id' => $order->id, 'logistic_number' => $logisticNumber]);
+        return compact('orderPackage', 'order');
     }
 
     public function syncOrderPackage(&$orderHeaders)
@@ -111,84 +119,84 @@ class OrderPackageService
     {
         /** @var OrderService $orderService */
         $orderService = app('OrderService');
-        if(!$orderHeaders)return;
+        if (!$orderHeaders) return;
         $orders = $orderService->getByWmsOrders($orderHeaders);
         $this->processCancelOrderPackages($orderHeaders);                           // 取消订单操作 及 过滤
-        $packages = $this->getByOrderNos(data_get($orderHeaders,'*.orderno'));          // 已有
-        $this->createOrderPackage($orderHeaders,$orders,$packages);                     // 创建package
-        $this->updatePackage($orderHeaders,$packages);
-        $this->deleteUnnecessaryPackage($orderHeaders,$packages);     // 删除package
-        unset($orders,$packages);       // 手动清除
+        $packages = $this->getByOrderNos(data_get($orderHeaders, '*.orderno'));          // 已有
+        $this->createOrderPackage($orderHeaders, $orders, $packages);                     // 创建package
+        $this->updatePackage($orderHeaders, $packages);
+        $this->deleteUnnecessaryPackage($orderHeaders, $packages);     // 删除package
+        unset($orders, $packages);       // 手动清除
     }
 
-    public function createOrderPackage($orderHeaders,$orders,$packages)
+    public function createOrderPackage($orderHeaders, $orders, $packages)
     {
-        if(!$orderHeaders)return;
+        if (!$orderHeaders) return;
         /**
          * @var DataHandlerService $dataHandlerService
          * @var LogisticService $logsitcService
          */
         $logisticService = app(LogisticService::class);
         $dataHandlerService = app(DataHandlerService::class);
-        $orderHeaders_map = $dataHandlerService->dataHeader(['orderno'],$orderHeaders);
-        $packages_maps = $dataHandlerService->dataHeader(['logistic_number'],$packages);
+        $orderHeaders_map = $dataHandlerService->dataHeader(['orderno'], $orderHeaders);
+        $packages_maps = $dataHandlerService->dataHeader(['logistic_number'], $packages);
         $inner_params = [];
 
         /** 定制京东快递的订单 */
         $logistic = $logisticService->getLogisticByCodes(['JDKD'])->first();
-        foreach ($orders as $order){
-            $orderHeader = $dataHandlerService->getKeyValue(['orderno'=>$order->code],$orderHeaders_map);
-            if(!$orderHeader)continue;
-            if($orderHeader->sostatus == 90)continue;
-            $params = $this->getInnerParams($orderHeader,$order,$packages_maps,$logistic);
-            $inner_params = array_merge($inner_params,$params);
+        foreach ($orders as $order) {
+            $orderHeader = $dataHandlerService->getKeyValue(['orderno' => $order->code], $orderHeaders_map);
+            if (!$orderHeader) continue;
+            if ($orderHeader->sostatus == 90) continue;
+            $params = $this->getInnerParams($orderHeader, $order, $packages_maps, $logistic);
+            $inner_params = array_merge($inner_params, $params);
         }
 
         /** 批量添加 */
-        if(count($inner_params)>0){
+        if (count($inner_params) > 0) {
             try {
-                $inner_array = array_chunk($inner_params,5000);
+                $inner_array = array_chunk($inner_params, 5000);
                 foreach ($inner_array as $params) {
                     $bool = $this->insert($params);
                     $bool ? LogService::log(__METHOD__, __FUNCTION__, '批量添加 OrderPackage ' . count($inner_params) . ' || ' . json_encode($inner_params)) : null;
                 }
             } catch (\Exception $e) {
-                LogService::log(__METHOD__, __FUNCTION__, '批量添加 OrderPackage error ' . count($inner_params) . ' || ' .json_encode($e->getMessage()). json_encode($inner_params).json_encode($e->getTraceAsString()));
+                LogService::log(__METHOD__, __FUNCTION__, '批量添加 OrderPackage error ' . count($inner_params) . ' || ' . json_encode($e->getMessage()) . json_encode($inner_params) . json_encode($e->getTraceAsString()));
             }
         }
     }
 
-    public function getInnerParams($orderHeader,$order,$packages_maps,$logistic): array
+    public function getInnerParams($orderHeader, $order, $packages_maps, $logistic): array
     {
         /**
-        * @var DataHandlerService $dataHandlerService
-        */
+         * @var DataHandlerService $dataHandlerService
+         */
         $dataHandlerService = app('DataHandlerService');
-        $logistic_numbers = array_diff(array_unique(data_get($orderHeader->actAllocationDetails,'*.picktotraceid')),['','*']);
+        $logistic_numbers = array_diff(array_unique(data_get($orderHeader->actAllocationDetails, '*.picktotraceid')), ['', '*']);
         $date = Carbon::now()->format('Y-m-d H:i:s');
         $inner_params = [];
         $sentAtMap = [];
 
-        if($orderHeader['sostatus'] == '90'){
-            if($orderHeader['soreference5']=='')$logistic_numbers = [$orderHeader['orderno']];
+        if ($orderHeader['sostatus'] == '90') {
+            if ($orderHeader['soreference5'] == '') $logistic_numbers = [$orderHeader['orderno']];
             else $logistic_numbers = [$orderHeader['soreference5']];
         }
 
         /** sent_at checktime */
-        foreach ($orderHeader->actAllocationDetails as $item){
+        foreach ($orderHeader->actAllocationDetails as $item) {
             $sentAtMap[$item->picktotraceid] = $item;
         }
 
         /** 承运商是京东时的定制操作 */
-        if($order['logistic_id'] == $logistic['id'] && count($logistic_numbers) == 1){
+        if ($order['logistic_id'] == $logistic['id'] && count($logistic_numbers) == 1) {
             $logistic_numbers = [$orderHeader['soreference5']];
             $sentAtMap[$orderHeader['soreference5']] = $orderHeader->actAllocationDetails->first() ?? null;
         }
 
-        foreach ($logistic_numbers as $logistic_number){
-            $package = $dataHandlerService->getKeyValue(['logistic_number'=>$logistic_number],$packages_maps);
+        foreach ($logistic_numbers as $logistic_number) {
+            $package = $dataHandlerService->getKeyValue(['logistic_number' => $logistic_number], $packages_maps);
 
-            if(isset($package))continue;
+            if (isset($package)) continue;
             try {
                 $data = $sentAtMap[$logistic_number];
             } catch (\Exception $e) {
@@ -202,14 +210,14 @@ class OrderPackageService
                 'updated_at' => $date,
                 'status' => '无',
                 'owner_id' => $order->owner_id,
-                'sent_at' => $data ? $data->checktime:null,
+                'sent_at' => $data ? $data->checktime : null,
             ];
         }
         return $inner_params;
     }
 
 
-    public function deleteUnnecessaryPackage($orderHeaders,$packages)
+    public function deleteUnnecessaryPackage($orderHeaders, $packages)
     {
         /**
          * @var DataHandlerService $dataHandlerService
@@ -221,45 +229,45 @@ class OrderPackageService
 
         $logistic_numbers = array();
         foreach ($orderHeaders as $orderHeader) {
-            if($orderHeader['sostatus'] == '90') {
-                if($orderHeader['soreference5'] == '') $logistic_numbers[$orderHeader['orderno']] = $orderHeader['orderno'];
+            if ($orderHeader['sostatus'] == '90') {
+                if ($orderHeader['soreference5'] == '') $logistic_numbers[$orderHeader['orderno']] = $orderHeader['orderno'];
                 else $logistic_numbers[$orderHeader['soreference5']] = $orderHeader['soreference5'];
-            } elseif ($orderHeader['userdefine1'] == 'JDKD' ){
+            } elseif ($orderHeader['userdefine1'] == 'JDKD') {
                 $logistic_numbers[$orderHeader['soreference5']] = $orderHeader['soreference5'];
             } else {
                 foreach ($orderHeader->actAllocationDetails as $actAllocationDetail) {
-                    $logistic_numbers[$actAllocationDetail['picktotraceid']] =  $actAllocationDetail['picktotraceid'];
+                    $logistic_numbers[$actAllocationDetail['picktotraceid']] = $actAllocationDetail['picktotraceid'];
                 }
             }
         }
 
         /** WMS快递单号唯一化 剔除 '',' ','*'*/
         $logistic_numbers = array_unique(array_values($logistic_numbers));
-        $logistic_numbers = array_diff($logistic_numbers,['',' ','*']);
+        $logistic_numbers = array_diff($logistic_numbers, ['', ' ', '*']);
 
         /** WAS数据库中已有的快递单号*/
-        $packages_maps = $dataHandlerService->dataHeader(['logistic_number'],$packages);
-        $exits_number = data_get($packages,'*.logistic_number');
+        $packages_maps = $dataHandlerService->dataHeader(['logistic_number'], $packages);
+        $exits_number = data_get($packages, '*.logistic_number');
 
         /** WMS快递单号 和 WAS的快递单号 的差集*/
         $packages = array();
-        $diff_number = array_diff($exits_number,$logistic_numbers);
+        $diff_number = array_diff($exits_number, $logistic_numbers);
 
         /** 记录差集对应的OrderPackage的id*/
         foreach ($diff_number as $number) {
-            $package = $dataHandlerService->getKeyValue(['logistic_number'=>$number],$packages_maps);
-            if($package ?? false)$packages[]=$package->id;
+            $package = $dataHandlerService->getKeyValue(['logistic_number' => $number], $packages_maps);
+            if ($package ?? false) $packages[] = $package->id;
         }
 
         /** 删除 OrderPackage 和 OrderPackageCommodities*/
-        if(count($packages)==0)return;
+        if (count($packages) == 0) return;
         try {
             $bool = OrderPackage::query()->whereIn('id', $packages)->delete();
-            $orderPackageCommodities = OrderPackageCommodities::query()->whereIn('order_package_id',$packages)->get();
+            $orderPackageCommodities = OrderPackageCommodities::query()->whereIn('order_package_id', $packages)->get();
             $orderPackageCommoditiesService->deleteOrderCommodities($orderPackageCommodities);
-            $bool ? LogService::log(__METHOD__,__FUNCTION__,'删除多余包裹 ids:'.json_encode($packages)) : null;
+            $bool ? LogService::log(__METHOD__, __FUNCTION__, '删除多余包裹 ids:' . json_encode($packages)) : null;
         } catch (\Exception $e) {
-            LogService::log(__METHOD__,__FUNCTION__,'删除多余包裹 ids:'.json_encode($packages).$e->getMessage());
+            LogService::log(__METHOD__, __FUNCTION__, '删除多余包裹 ids:' . json_encode($packages) . $e->getMessage());
         }
     }
 
@@ -267,7 +275,7 @@ class OrderPackageService
     {
         $map = $this->getSentAtMap($orderHeaders);
         $update_params = [];
-        $update_params[] = ['id','sent_at'];
+        $update_params[] = ['id', 'sent_at'];
         foreach ($packages as $package) {
             if ($package->sent_at) continue;
             try {
@@ -280,7 +288,7 @@ class OrderPackageService
                     'id' => $package->id,
                     'sent_at' => $checktime,
                 ];
-            }else {
+            } else {
                 continue;
             }
 
@@ -311,28 +319,105 @@ class OrderPackageService
      */
     public function processCancelOrderPackages(&$orderHeaders)
     {
-        $this->instant($this->orderTrackingService,'OrderTrackingService');
+        $this->instant($this->orderTrackingService, 'OrderTrackingService');
 
-        $cancelOrder = $orderHeaders->filter(function($orderHeader){
+        $cancelOrder = $orderHeaders->filter(function ($orderHeader) {
             return $orderHeader->sostatus == '90';
         });
 
-        $orderPackages = OrderPackage::query()->whereIn('order_id',function($query)use($cancelOrder){
+        $orderPackages = OrderPackage::query()->whereIn('order_id', function ($query) use ($cancelOrder) {
             /** @var Builder $query */
-            $query->from((new Order())->getTable())->selectRaw('id')->whereIn('code',data_get($cancelOrder,'*.orderno'));
+            $query->from((new Order())->getTable())->selectRaw('id')->whereIn('code', data_get($cancelOrder, '*.orderno'));
         })->get();
 
-        if($orderPackages->count() == 0)return ;
+        if ($orderPackages->count() == 0) return;
 
         $orderPackage_list = $orderPackages->chunk(200);
-        foreach ($orderPackage_list as $orderPackageSet){
-            OrderPackage::query()->whereIn('id',data_get($orderPackageSet,'*.id'))->delete();
-            $items = OrderTracking::query()->whereIn('order_package_commodity_id',function($query)use($orderPackages){
+        foreach ($orderPackage_list as $orderPackageSet) {
+            OrderPackage::query()->whereIn('id', data_get($orderPackageSet, '*.id'))->delete();
+            $items = OrderTracking::query()->whereIn('order_package_commodity_id', function ($query) use ($orderPackages) {
                 /** @var Builder $query */
-                $query->from((new OrderPackageCommodities)->getTable())->selectRaw('id')->whereIn('order_package_id',data_get($orderPackages,'*.id'));
+                $query->from((new OrderPackageCommodities)->getTable())->selectRaw('id')->whereIn('order_package_id', data_get($orderPackages, '*.id'));
             })->get();
             $this->orderTrackingService->deleteOrderTracings($items);
         }
 
     }
+
+    /**
+     * 一键揽收上传
+     * @param $logistic_numbers array
+     * @return array
+     */
+    public function collectUpload(array $logistic_numbers=[]): array
+    {
+        //参数校验
+        if (empty($logistic_numbers)) {
+            return [
+                'success' => false,
+                'message' => '输入快递单号为空',
+            ];
+        }
+        $orderPackageCount = OrderPackage::query()->whereIn('logistic_number', $logistic_numbers)
+            ->whereIn('order_id', function ($query) {
+                $query->from('orders')->select('id')->whereIn('logistic_id', function ($query) {
+                    $query->from('logistics')->select('id')->whereIn('code', [
+                        'ZTO',
+                        'ZTO-1',
+                        'WPZTO',
+                    ]);
+                });
+            })->count();
+        if ($orderPackageCount !== count($logistic_numbers)) {
+            return [
+                'success' => false,
+                'message' => '输入的快递单号异常,请检查承运商是否全部为中通',
+            ];
+        }
+
+        $url = config('api_logistic.collectUpload.ZTO.test.url');
+        $xAppKey = config('api_logistic.collectUpload.ZTO.test.x-appKey');
+        $appSecret = config('api_logistic.collectUpload.ZTO.test.appSecret');
+        $appId = config('api_logistic.collectUpload.ZTO.test.appId');
+        //中通接口最大支持100条
+        $logistic_numbers_chunked = array_chunk($logistic_numbers, 100);
+
+        foreach ($logistic_numbers_chunked as $logistic_numbers_chunked_items) {
+            $orderPackages = OrderPackage::query()
+                ->select('weight', 'logistic_number')
+                ->whereIn('logistic_number', $logistic_numbers_chunked_items)->get();
+
+            $collectUploadDTOS = [];
+
+            foreach ($orderPackages as $orderPackage) {
+                $collectUploadDTOS[] = [
+                    'billCode' => $orderPackage->logistic_number,
+                    'weight' => $orderPackage->weight ?? 0,
+                    'appId' => $appId,
+                    'importDate' => now()->toDateTimeString(),
+                ];
+            }
+            $body = json_encode([
+                'collectUploadDTOS' => $collectUploadDTOS,
+            ], JSON_UNESCAPED_UNICODE);
+            $data_digest = base64_encode(md5($body . $appSecret, TRUE));
+            $headers = [
+                'Content-Type' => 'application/json; charset=UTF-8',
+                'x-companyid' => $xAppKey,
+                'x-datadigest' => $data_digest,
+            ];
+            $response = Http::withHeaders($headers)->withBody($body, 'application/json')->post($url);
+            $responseBody = json_decode($response->body());
+            if ($responseBody->statusCode === 'S210' ||//无权限
+                $responseBody->statusCode === 'PARAM_ERROR'||//揽收上传信息为空
+                $responseBody->statusCode === 'SYSTEM_ERROR'//系统异常,请联系系统管理员
+            ) {
+                return [
+                    'success' => false,
+                    'message' => $responseBody->message,
+                ];
+            }
+        }
+        return ['success' => true, 'message' => '一键揽收上传成功'];
+    }
 }

+ 237 - 0
app/Services/ReviewService.php

@@ -0,0 +1,237 @@
+<?php
+
+namespace App\Services;
+
+use App\OracleActAllocationDetails;
+use App\OracleDOCOrderHeader;
+use App\OracleDOCOrderPackings;
+use App\Traits\ServiceAppAop;
+use Doctrine\DBAL\Driver\PDOConnection;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\DB;
+use PDO;
+
+class ReviewService
+{
+    use ServiceAppAop;
+
+    //单品复核
+
+
+    /**
+     * @param $IN_Warehouse
+     * @param $IN_CustomerID
+     * @param $IN_WaveNo
+     * @param $IN_SKU
+     * @param $IN_CheckModule
+     * @param $IN_WorkStation
+     * @param $IN_Language
+     * @param $IN_UserID
+     * @param $OUT_AllocationDetailsID
+     * @param $OUT_TOID
+     * @param $OUT_OrderNo
+     * @param $OUT_Return_Code
+     */
+    public function single($IN_Warehouse, $IN_CustomerID, $IN_WaveNo, $IN_SKU, $IN_CheckModule, $IN_WorkStation, $IN_Language, $IN_UserID, $OUT_AllocationDetailsID, $OUT_TOID, $OUT_OrderNo, $OUT_Return_Code)
+    {
+
+        DB::beginTransaction();
+
+
+        try {
+            $r_CurrentTime = now()->toDateTimeString();
+            $r_SGL_ORD_PCK = $this->getsys_configuration($IN_Warehouse, '*', '*', 'SGL_ORD_PCK');//防止并发错误
+            $sql = <<<sql
+Select a.OrderNo,AllocationDetailsID,a.SKU,PickToTraceID
+                          ,c.CarrierID, requiredeliveryno, nvl(c.channel,' * ')
+                         ,c.Erpcancelflag
+                   From ACT_Allocation_Details a inner join
+                    DOC_Order_Details b on a.OrderNo=b.OrderNo and a.OrderLineNo=b.OrderLineNo inner join
+                     DOC_Order_Header c on b.OrderNo=c.OrderNo
+sql;
+            if ((!empty($IN_WaveNo)) && $IN_WaveNo !== '*') {
+                $sql .= " inner join DOC_Wave_Details d on d.OrderNo=c.OrderNo  and d.WaveNo=:WaveNo  and a.WaveNo=:WaveNo ";
+            }
+            $sql .= " Where a.CustomerID=:CustomerID and a.SKU=:SKU and c.SingleMatch='Y'
+                     and b.CommingleSKU='N' and a.PackFlag='N'
+                     and c.releasestatus <> 'H'
+                     and c.Warehouseid = :Warehouse
+                     AND c.Sostatus < '80' ";
+            if ($r_SGL_ORD_PCK === 'N' || $r_SGL_ORD_PCK === 'NO') {
+                $sql .= " and a.status <'80' ";
+            } else {
+                $sql .= " and a.status <'60' ";
+            }
+            $sql .= " and not exists(select 1 from SYS_Check_Exception where AllocationDetailsID = a.AllocationDetailsID and  taskprocess<>'99' )
+                     and rownum = 1 for update";
+            $result = DB::connection('oracle')->selectOne(DB::raw($sql), [
+                'WaveNo' => $IN_WaveNo,
+                'CustomerID' => $IN_CustomerID,
+                'Warehouse' => $IN_Warehouse,
+            ]);
+            $OUT_OrderNo = $result->OrderNo;
+            $OUT_AllocationDetailsID = $result->AllocationDetailsID;
+            $r_SKU = $result->SKU;
+            $r_PickToTraceID = $result->PickToTraceID;
+            $r_CarrierID = $result->CarrierID;
+            $r_requiredeliveryno = $result->requiredeliveryno;
+            $r_channel = $result->channel;
+            $r_Erpcancelflag = $result->Erpcancelflag;
+            //更新分配详情
+            OracleActAllocationDetails::query()
+                ->where('allocationdetailsid', $OUT_AllocationDetailsID)
+                ->update([
+                    'CheckModule' => $IN_CheckModule,
+                ]);
+            if ($r_Erpcancelflag === 'Y') {
+                $OUT_Return_Code = '000CANCEL';
+            }
+            //如果复核时没有使用新的ID,则取分配明细的ID
+            if (empty($OUT_TOID) || $OUT_TOID === '*') {
+                $r_DEL_DOC_SN = $this->lock($IN_Warehouse, $IN_CustomerID, '*', 'DEL_DOC_SN#');
+                if ($r_DEL_DOC_SN === 'C' && $r_requiredeliveryno === 'Y') {
+                    $OUT_Return_Code = '*_*';
+                    $r_ParaTemp = 'DELIVERYNO' . $OUT_OrderNo;
+                    // 获取数据表的ID(PO, ASN, SO...)
+                    list($IN_Warehouse, $IN_Language, $r_ParaTemp, $OUT_TOID, $OUT_Return_Code) = $this->SPCOM_GetIDSequence($IN_Warehouse, $IN_Language, $r_ParaTemp, $OUT_TOID, $OUT_Return_Code);
+                    if (substr($OUT_Return_Code, 0, 3) !== '000') {
+                        return;
+                    }
+                } else {
+                    $OUT_TOID = $r_PickToTraceID;
+                }
+            }
+            //取消装箱确认
+            OracleDOCOrderPackings::query()
+                ->where('TraceID', $OUT_TOID)
+                ->delete();
+
+            OracleDOCOrderPackings::query()->create([
+                'TraceID' => $OUT_TOID,
+                'SKU' => $IN_SKU,
+                'OrderNo' => $OUT_OrderNo,
+                'Qty' => 1,
+                'AddTime' => $r_CurrentTime,
+                'AddWho' => $IN_UserID,
+                'EditTime' => $r_CurrentTime,
+                'EditWho' => $IN_UserID,
+                'AllocationDetailsID' => $OUT_AllocationDetailsID,
+                'FROMTRACEID' => $OUT_TOID,
+            ]);
+            DB::commit();
+            $OUT_Return_Code = '*_*SINGLE';
+
+
+            list ($IN_Warehouse, $IN_CHK_TYP, $IN_TraceID, $IN_CheckModule, $IN_WorkStation, $IN_Language, $IN_UserID, $OUT_Return_Code) =
+                $this->SPSO_Cartonization_Process($IN_Warehouse, 'ORDER', $OUT_TOID, $IN_CheckModule, $IN_WorkStation, $IN_Language, $IN_UserID, $OUT_Return_Code);
+            if (substr($OUT_Return_Code, 1, 3) !== '000') {
+                DB::rollBack();
+                return;
+            }
+            if (!OracleActAllocationDetails::query()->where('orderno', $OUT_OrderNo)->where('PackFlag', 'N')->where('rownum', 1)->exists()) {
+                OracleDOCOrderHeader::query()
+                    ->where('orderno', $OUT_OrderNo)
+                    ->update([
+                        'ReleaseStatus' => 'Y',
+                    ]);
+            }
+            DB::commit();
+            $OUT_Return_Code = '000';
+        } catch (\Exception $e) {
+            DB::rollBack();
+        }
+    }
+
+    public function getsys_configuration($IN_WarehouseID, $IN_CustomerID, $IN_OrderType, $IN_ConfigID, $IN_DefaultValue = 'N', $IN_ValueType = 'C')
+    {
+        $conn = $this->getOciConnection();
+        $sql_sp = "begin GETSYS_configuration(
+        :IN_WarehouseID,
+        :IN_CustomerID,
+        :IN_OrderType,
+        :IN_ConfigID,
+        :IN_DefaultValue,
+        :IN_ValueType
+        ); end;";
+        $stmt = oci_parse($conn, $sql_sp);
+        oci_bind_by_name($stmt, ':IN_WarehouseID', $IN_WarehouseID);
+        oci_bind_by_name($stmt, ':IN_CustomerID', $IN_CustomerID);
+        oci_bind_by_name($stmt, ':IN_OrderType', $IN_OrderType);
+        oci_bind_by_name($stmt, ':IN_ConfigID', $IN_ConfigID);
+        oci_bind_by_name($stmt, ':IN_DefaultValue', $IN_DefaultValue);
+        oci_bind_by_name($stmt, ':IN_ValueType', $IN_ValueType);
+        $r_SGL_ORD_PCK =  oci_execute($stmt);
+        oci_close($conn);
+        return $r_SGL_ORD_PCK;
+    }
+
+    public function SPSO_Cartonization_Process($IN_Warehouse, $IN_CHK_TYP, $IN_TraceID, $IN_CheckModule, $IN_WorkStation, $IN_Language, $IN_UserID, $OUT_Return_Code): array
+    {
+        $conn = $this->getOciConnection();
+        $sql_sp = "begin SPCOM_GetIDSequence(
+        :IN_Warehouse,
+        :IN_CHK_TYP,
+        :IN_TraceID,
+        :IN_CheckModule,
+        :IN_WorkStation
+        :IN_Language
+        :IN_UserID
+        :OUT_Return_Code
+        ); end;";
+        $stmt = oci_parse($conn, $sql_sp);
+        oci_bind_by_name($stmt, ':IN_Warehouse', $IN_Warehouse);
+        oci_bind_by_name($stmt, ':IN_CHK_TYP', $IN_CHK_TYP);
+        oci_bind_by_name($stmt, ':IN_TraceID', $IN_TraceID);
+        oci_bind_by_name($stmt, ':IN_CheckModule', $IN_CheckModule);
+        oci_bind_by_name($stmt, ':IN_WorkStation', $IN_WorkStation);
+        oci_bind_by_name($stmt, ':IN_Language', $IN_Language);
+        oci_bind_by_name($stmt, ':IN_UserID', $IN_UserID);
+        oci_bind_by_name($stmt, ':OUT_Return_Code', $OUT_Return_Code);
+        oci_execute($stmt);
+        oci_close($conn);
+        return array($IN_Warehouse, $IN_CHK_TYP, $IN_TraceID, $IN_CheckModule, $IN_WorkStation, $IN_Language, $IN_UserID, $OUT_Return_Code);
+    }
+
+
+    /**
+     * 获取数据表的ID(PO, ASN, SO...)
+     * @param $IN_Warehouse
+     * @param $IN_Language
+     * @param $r_ParaTemp
+     * @param $OUT_TOID
+     * @param $OUT_Return_Code
+     * @return array
+     */
+    public function SPCOM_GetIDSequence($IN_Warehouse, $IN_Language, $r_ParaTemp, $OUT_TOID, $OUT_Return_Code): array
+    {
+        $conn = $this->getOciConnection();
+        $sql_sp = "begin SPCOM_GetIDSequence(
+        :IN_Warehouse,
+        :IN_Language,
+        :r_ParaTemp,
+        :OUT_TOID,
+        :OUT_Return_Code
+        ); end;";
+        $stmt = oci_parse($conn, $sql_sp);
+        oci_bind_by_name($stmt, ':IN_Warehouse', $IN_Warehouse);
+        oci_bind_by_name($stmt, ':IN_Language', $IN_Language);
+        oci_bind_by_name($stmt, ':r_ParaTemp', $r_ParaTemp);
+        oci_bind_by_name($stmt, ':OUT_TOID', $OUT_TOID);
+        oci_bind_by_name($stmt, ':OUT_Return_Code', $OUT_Return_Code);
+        oci_execute($stmt);
+        oci_close($conn);
+        return array($IN_Warehouse, $IN_Language, $r_ParaTemp, $OUT_TOID, $OUT_Return_Code);
+    }
+
+    /**
+     * @return false|resource
+     */
+    private function getOciConnection()
+    {
+        $username = config('database.connections.oracle.username');
+        $password = config('database.connections.oracle.password');
+        $host = config('database.connections.oracle.host');
+        $service_name = config('database.connections.oracle.service_name');
+        return oci_connect($username, $password, $host . '/' . $service_name, 'utf8'); //连接oracle数据库
+    }
+}

+ 1 - 0
app/Services/StationTaskMaterialBoxService.php

@@ -118,6 +118,7 @@ class StationTaskMaterialBoxService
         //$orderCommodities=$orderCommodities->sortBy('commodity_id');//按商品排序后,出货可以同商品挨在一起
         foreach ($orderCommodities as $orderCommodity){
             $station=$this->stationService->getStation_byType($stationType['name']);
+            if (!$this->materialBoxService->checkBoxNorm($orderCommodity['location']))continue;
             $materialBox=$this->materialBoxService->firstOrCreate(['code' => $orderCommodity['location']]);
             if(in_array($materialBox['id'],$materialBoxIds_used))continue;
             $stationMaterialBoxes_toCreate->push([

+ 6 - 5
app/Traits/LogisticSyncTrait.php

@@ -76,7 +76,7 @@ trait LogisticSyncTrait
                 });
 
                 $last_transfer = $transfer_status[0]['accept_time'];
-                $last_remark = $transfer_status[0]['remark'];
+                $last_remark = empty(!$transfer_status[0]['remark'])?:$transfer_status[0]['accept_address'];
                 if (count($transfer_status) <= 3) {//三条以内的不管地区 时间限制为24h
                     if (Carbon::parse($last_transfer)->diffInHours(now()) > 24) {
                         $data['exception_status'] = '在途异常';
@@ -126,13 +126,14 @@ trait LogisticSyncTrait
                         $data['exception_status'] = '在途异常';
                     }
                 }
-                if (Str::contains($last_remark,['代收','快递柜','驿站','自提柜','丰巢','快递小屋','合作点','快递超市'])) {
-                    $data['exception_status'] = '';
-                    $data['status'] = '已签收';
-                }
+
                 if ($data['exception_status']??''==='在途异常'&& $data['status']== '派送中') {
                     $data['exception_status'] = '派送异常';
                 }
+                if (Str::contains($last_remark,['代收','快递柜','驿站','自提柜','丰巢','快递小屋','合作点','快递超市','签收'])) {
+                    $data['exception_status'] = '';
+                    $data['status'] = '已签收';
+                }
             }
         }
         return $data;

+ 0 - 7
bootstrap/cache/packages.php

@@ -1,11 +1,4 @@
 <?php return array (
-  'beyondcode/laravel-dump-server' => 
-  array (
-    'providers' => 
-    array (
-      0 => 'BeyondCode\\DumpServer\\DumpServerServiceProvider',
-    ),
-  ),
   'facade/ignition' => 
   array (
     'providers' => 

+ 36 - 38
bootstrap/cache/services.php

@@ -23,25 +23,24 @@
     19 => 'Illuminate\\Translation\\TranslationServiceProvider',
     20 => 'Illuminate\\Validation\\ValidationServiceProvider',
     21 => 'Illuminate\\View\\ViewServiceProvider',
-    22 => 'BeyondCode\\DumpServer\\DumpServerServiceProvider',
-    23 => 'Facade\\Ignition\\IgnitionServiceProvider',
-    24 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider',
-    25 => 'Intervention\\Image\\ImageServiceProvider',
-    26 => 'Laravel\\Horizon\\HorizonServiceProvider',
-    27 => 'Laravel\\Ui\\UiServiceProvider',
-    28 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
-    29 => 'Carbon\\Laravel\\ServiceProvider',
-    30 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
-    31 => 'Oursdreams\\Export\\ExportServiceProvider',
-    32 => 'Overtrue\\LaravelPinyin\\ServiceProvider',
-    33 => 'Te7aHoudini\\LaravelTrix\\LaravelTrixServiceProvider',
-    34 => 'Yajra\\Oci8\\Oci8ServiceProvider',
-    35 => 'App\\Providers\\AppServiceProvider',
-    36 => 'App\\Providers\\AuthServiceProvider',
-    37 => 'App\\Providers\\BroadcastServiceProvider',
-    38 => 'App\\Providers\\EventServiceProvider',
-    39 => 'App\\Providers\\HorizonServiceProvider',
-    40 => 'App\\Providers\\RouteServiceProvider',
+    22 => 'Facade\\Ignition\\IgnitionServiceProvider',
+    23 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider',
+    24 => 'Intervention\\Image\\ImageServiceProvider',
+    25 => 'Laravel\\Horizon\\HorizonServiceProvider',
+    26 => 'Laravel\\Ui\\UiServiceProvider',
+    27 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
+    28 => 'Carbon\\Laravel\\ServiceProvider',
+    29 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
+    30 => 'Oursdreams\\Export\\ExportServiceProvider',
+    31 => 'Overtrue\\LaravelPinyin\\ServiceProvider',
+    32 => 'Te7aHoudini\\LaravelTrix\\LaravelTrixServiceProvider',
+    33 => 'Yajra\\Oci8\\Oci8ServiceProvider',
+    34 => 'App\\Providers\\AppServiceProvider',
+    35 => 'App\\Providers\\AuthServiceProvider',
+    36 => 'App\\Providers\\BroadcastServiceProvider',
+    37 => 'App\\Providers\\EventServiceProvider',
+    38 => 'App\\Providers\\HorizonServiceProvider',
+    39 => 'App\\Providers\\RouteServiceProvider',
   ),
   'eager' => 
   array (
@@ -55,25 +54,24 @@
     7 => 'Illuminate\\Pagination\\PaginationServiceProvider',
     8 => 'Illuminate\\Session\\SessionServiceProvider',
     9 => 'Illuminate\\View\\ViewServiceProvider',
-    10 => 'BeyondCode\\DumpServer\\DumpServerServiceProvider',
-    11 => 'Facade\\Ignition\\IgnitionServiceProvider',
-    12 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider',
-    13 => 'Intervention\\Image\\ImageServiceProvider',
-    14 => 'Laravel\\Horizon\\HorizonServiceProvider',
-    15 => 'Laravel\\Ui\\UiServiceProvider',
-    16 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
-    17 => 'Carbon\\Laravel\\ServiceProvider',
-    18 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
-    19 => 'Oursdreams\\Export\\ExportServiceProvider',
-    20 => 'Overtrue\\LaravelPinyin\\ServiceProvider',
-    21 => 'Te7aHoudini\\LaravelTrix\\LaravelTrixServiceProvider',
-    22 => 'Yajra\\Oci8\\Oci8ServiceProvider',
-    23 => 'App\\Providers\\AppServiceProvider',
-    24 => 'App\\Providers\\AuthServiceProvider',
-    25 => 'App\\Providers\\BroadcastServiceProvider',
-    26 => 'App\\Providers\\EventServiceProvider',
-    27 => 'App\\Providers\\HorizonServiceProvider',
-    28 => 'App\\Providers\\RouteServiceProvider',
+    10 => 'Facade\\Ignition\\IgnitionServiceProvider',
+    11 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider',
+    12 => 'Intervention\\Image\\ImageServiceProvider',
+    13 => 'Laravel\\Horizon\\HorizonServiceProvider',
+    14 => 'Laravel\\Ui\\UiServiceProvider',
+    15 => 'Maatwebsite\\Excel\\ExcelServiceProvider',
+    16 => 'Carbon\\Laravel\\ServiceProvider',
+    17 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
+    18 => 'Oursdreams\\Export\\ExportServiceProvider',
+    19 => 'Overtrue\\LaravelPinyin\\ServiceProvider',
+    20 => 'Te7aHoudini\\LaravelTrix\\LaravelTrixServiceProvider',
+    21 => 'Yajra\\Oci8\\Oci8ServiceProvider',
+    22 => 'App\\Providers\\AppServiceProvider',
+    23 => 'App\\Providers\\AuthServiceProvider',
+    24 => 'App\\Providers\\BroadcastServiceProvider',
+    25 => 'App\\Providers\\EventServiceProvider',
+    26 => 'App\\Providers\\HorizonServiceProvider',
+    27 => 'App\\Providers\\RouteServiceProvider',
   ),
   'deferred' => 
   array (

+ 44 - 42
composer.lock

@@ -356,16 +356,16 @@
         },
         {
             "name": "doctrine/dbal",
-            "version": "2.13.2",
+            "version": "2.13.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/dbal.git",
-                "reference": "8dd39d2ead4409ce652fd4f02621060f009ea5e4"
+                "reference": "0d7adf4cadfee6f70850e5b163e6cdd706417838"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/8dd39d2ead4409ce652fd4f02621060f009ea5e4",
-                "reference": "8dd39d2ead4409ce652fd4f02621060f009ea5e4",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/0d7adf4cadfee6f70850e5b163e6cdd706417838",
+                "reference": "0d7adf4cadfee6f70850e5b163e6cdd706417838",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -383,13 +383,14 @@
             },
             "require-dev": {
                 "doctrine/coding-standard": "9.0.0",
-                "jetbrains/phpstorm-stubs": "2020.2",
-                "phpstan/phpstan": "0.12.81",
+                "jetbrains/phpstorm-stubs": "2021.1",
+                "phpstan/phpstan": "0.12.96",
                 "phpunit/phpunit": "^7.5.20|^8.5|9.5.5",
+                "psalm/plugin-phpunit": "0.16.1",
                 "squizlabs/php_codesniffer": "3.6.0",
                 "symfony/cache": "^4.4",
                 "symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
-                "vimeo/psalm": "4.6.4"
+                "vimeo/psalm": "4.10.0"
             },
             "suggest": {
                 "symfony/console": "For helpful console commands such as SQL execution and import of files."
@@ -450,7 +451,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/dbal/issues",
-                "source": "https://github.com/doctrine/dbal/tree/2.13.2"
+                "source": "https://github.com/doctrine/dbal/tree/2.13.3"
             },
             "funding": [
                 {
@@ -466,7 +467,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-06-18T21:48:39+00:00"
+            "time": "2021-09-12T19:11:48+00:00"
         },
         {
             "name": "doctrine/deprecations",
@@ -1091,16 +1092,16 @@
         },
         {
             "name": "facade/flare-client-php",
-            "version": "1.8.1",
+            "version": "1.9.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/facade/flare-client-php.git",
-                "reference": "47b639dc02bcfdfc4ebb83de703856fa01e35f5f"
+                "reference": "b2adf1512755637d0cef4f7d1b54301325ac78ed"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/facade/flare-client-php/zipball/47b639dc02bcfdfc4ebb83de703856fa01e35f5f",
-                "reference": "47b639dc02bcfdfc4ebb83de703856fa01e35f5f",
+                "url": "https://api.github.com/repos/facade/flare-client-php/zipball/b2adf1512755637d0cef4f7d1b54301325ac78ed",
+                "reference": "b2adf1512755637d0cef4f7d1b54301325ac78ed",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -1150,7 +1151,7 @@
             ],
             "support": {
                 "issues": "https://github.com/facade/flare-client-php/issues",
-                "source": "https://github.com/facade/flare-client-php/tree/1.8.1"
+                "source": "https://github.com/facade/flare-client-php/tree/1.9.1"
             },
             "funding": [
                 {
@@ -1158,20 +1159,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2021-05-31T19:23:29+00:00"
+            "time": "2021-09-13T12:16:46+00:00"
         },
         {
             "name": "facade/ignition",
-            "version": "2.12.0",
+            "version": "2.13.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/facade/ignition.git",
-                "reference": "74dcc32a2895a126d1e5f2cd3bbab499cac66db1"
+                "reference": "e3f49bef7b4165fa4b8a9dc579e7b63fa06aef78"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/facade/ignition/zipball/74dcc32a2895a126d1e5f2cd3bbab499cac66db1",
-                "reference": "74dcc32a2895a126d1e5f2cd3bbab499cac66db1",
+                "url": "https://api.github.com/repos/facade/ignition/zipball/e3f49bef7b4165fa4b8a9dc579e7b63fa06aef78",
+                "reference": "e3f49bef7b4165fa4b8a9dc579e7b63fa06aef78",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -1183,7 +1184,7 @@
             "require": {
                 "ext-json": "*",
                 "ext-mbstring": "*",
-                "facade/flare-client-php": "^1.6",
+                "facade/flare-client-php": "^1.9.1",
                 "facade/ignition-contracts": "^1.0.2",
                 "illuminate/support": "^7.0|^8.0",
                 "monolog/monolog": "^2.0",
@@ -1240,7 +1241,7 @@
                 "issues": "https://github.com/facade/ignition/issues",
                 "source": "https://github.com/facade/ignition"
             },
-            "time": "2021-08-24T09:53:54+00:00"
+            "time": "2021-09-13T13:01:30+00:00"
         },
         {
             "name": "facade/ignition-contracts",
@@ -3021,16 +3022,16 @@
         },
         {
             "name": "nesbot/carbon",
-            "version": "2.52.0",
+            "version": "2.53.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "369c0e2737c56a0f39c946dd261855255a6fccbe"
+                "reference": "f4655858a784988f880c1b8c7feabbf02dfdf045"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/369c0e2737c56a0f39c946dd261855255a6fccbe",
-                "reference": "369c0e2737c56a0f39c946dd261855255a6fccbe",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/f4655858a784988f880c1b8c7feabbf02dfdf045",
+                "reference": "f4655858a784988f880c1b8c7feabbf02dfdf045",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -3048,7 +3049,7 @@
             },
             "require-dev": {
                 "doctrine/orm": "^2.7",
-                "friendsofphp/php-cs-fixer": "^2.14 || ^3.0",
+                "friendsofphp/php-cs-fixer": "^3.0",
                 "kylekatarnls/multi-tester": "^2.0",
                 "phpmd/phpmd": "^2.9",
                 "phpstan/extension-installer": "^1.0",
@@ -3117,7 +3118,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-08-14T19:10:52+00:00"
+            "time": "2021-09-06T09:29:23+00:00"
         },
         {
             "name": "nikic/php-parser",
@@ -8407,16 +8408,16 @@
         },
         {
             "name": "mockery/mockery",
-            "version": "1.4.3",
+            "version": "1.4.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mockery/mockery.git",
-                "reference": "d1339f64479af1bee0e82a0413813fe5345a54ea"
+                "reference": "e01123a0e847d52d186c5eb4b9bf58b0c6d00346"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mockery/mockery/zipball/d1339f64479af1bee0e82a0413813fe5345a54ea",
-                "reference": "d1339f64479af1bee0e82a0413813fe5345a54ea",
+                "url": "https://api.github.com/repos/mockery/mockery/zipball/e01123a0e847d52d186c5eb4b9bf58b0c6d00346",
+                "reference": "e01123a0e847d52d186c5eb4b9bf58b0c6d00346",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -8479,9 +8480,9 @@
             ],
             "support": {
                 "issues": "https://github.com/mockery/mockery/issues",
-                "source": "https://github.com/mockery/mockery/tree/1.4.3"
+                "source": "https://github.com/mockery/mockery/tree/1.4.4"
             },
-            "time": "2021-02-24T09:51:49+00:00"
+            "time": "2021-09-13T15:28:59+00:00"
         },
         {
             "name": "myclabs/deep-copy",
@@ -8942,16 +8943,16 @@
         },
         {
             "name": "phpspec/prophecy",
-            "version": "1.13.0",
+            "version": "1.14.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
+                "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
-                "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e",
+                "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -8962,19 +8963,19 @@
             },
             "require": {
                 "doctrine/instantiator": "^1.2",
-                "php": "^7.2 || ~8.0, <8.1",
+                "php": "^7.2 || ~8.0, <8.2",
                 "phpdocumentor/reflection-docblock": "^5.2",
                 "sebastian/comparator": "^3.0 || ^4.0",
                 "sebastian/recursion-context": "^3.0 || ^4.0"
             },
             "require-dev": {
-                "phpspec/phpspec": "^6.0",
+                "phpspec/phpspec": "^6.0 || ^7.0",
                 "phpunit/phpunit": "^8.0 || ^9.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.11.x-dev"
+                    "dev-master": "1.x-dev"
                 }
             },
             "autoload": {
@@ -9009,9 +9010,9 @@
             ],
             "support": {
                 "issues": "https://github.com/phpspec/prophecy/issues",
-                "source": "https://github.com/phpspec/prophecy/tree/1.13.0"
+                "source": "https://github.com/phpspec/prophecy/tree/1.14.0"
             },
-            "time": "2021-03-17T13:42:18+00:00"
+            "time": "2021-09-10T09:02:12+00:00"
         },
         {
             "name": "phpunit/php-code-coverage",
@@ -10127,6 +10128,7 @@
                     "type": "github"
                 }
             ],
+            "abandoned": true,
             "time": "2020-11-30T07:30:19+00:00"
         },
         {

+ 28 - 11
config/api_logistic.php

@@ -118,7 +118,7 @@ return [
                 'url' => 'https://u-openapi.yundasys.com/openapi/outer/logictis/subscribe',
             ],
         ],
-        'prod'=>[
+        'prod' => [
             'app-key' => '000638',
             'app-secret' => '0b941e746e3e4a5687c11f11f32ef9a3',
             'search' => [
@@ -169,17 +169,17 @@ return [
     'init_date' => '2021-05-17 23:59:59',
     'querying_days' => 15,
     'DB' => [
-        'test'=>[
+        'test' => [
             'app_key' => 'bb4e6c0b24794795c306b3461f5470d3',
             'company_code' => 'EWBSHBSGYLGLYXGS',
             'customer_Code' => 'F2015082279473065',
             'sign' => 'IYKO',
             'needTraceInfo' => 0, //是否需要订阅轨迹 1:是 2:否
-            'orderType' => [1 => '散客模式',2 => '大客户模式',3 => '同步筛单下单'], //下单模式 1:散客模式 2:大客户模式 3:同步筛单下单
+            'orderType' => [1 => '散客模式', 2 => '大客户模式', 3 => '同步筛单下单'], //下单模式 1:散客模式 2:大客户模式 3:同步筛单下单
             'transportType' => ['JZQY_LONG' => '精准汽运', 'JZKH' => '精准卡航'], //运输方式/产品类型 快递运输方式 : RCP:大件快递360; NZBRH:重包入户; ZBTH:重包特惠; WXJTH:微小件特惠; JJDJ:经济大件; PACKAGE:标准快递; DEAP:特准快件;HKDJC:航空大件次日达; HKDJG:航空大件隔日达; TZKJC:特快专递; 零担运输方式: JZKY:精准空运(仅散客模式支持该运输方式); JZQY_LONG:精准汽运; JZKH:精准卡航; 整车运输方式 1.整车配送 ZCPS 2.精准专车 JZZHC
-            'payType' => [0 => '发货人付款(现付)(大客户模式不支持寄付)',1 => '收货人付款(到付)',2 => '发货人付款(月结)'], //支付方式  0、发货人付款(现付)(大客户模式不支持寄付) 1、收货人付款(到付) 2、发货人付款(月结)
-            'backSignBill' => [0 =>'无需返单',1 => '签收单原件返回',2 => '电子签收单'], //签收回单  0:无需返单 1:签收单原件返回 2:电子签收单(电子签名图片需要另外对接查询接口)
-            'packageService' => ['纸','纤','木箱','木架','托膜','托木'],  //包装(直接用中文) : 纸、纤、木箱、木架、托膜、托木(大客户模式下运输方式为零担时必填)
+            'payType' => [0 => '发货人付款(现付)(大客户模式不支持寄付)', 1 => '收货人付款(到付)', 2 => '发货人付款(月结)'], //支付方式  0、发货人付款(现付)(大客户模式不支持寄付) 1、收货人付款(到付) 2、发货人付款(月结)
+            'backSignBill' => [0 => '无需返单', 1 => '签收单原件返回', 2 => '电子签收单'], //签收回单  0:无需返单 1:签收单原件返回 2:电子签收单(电子签名图片需要另外对接查询接口)
+            'packageService' => ['纸', '纤', '木箱', '木架', '托膜', '托木'],  //包装(直接用中文) : 纸、纤、木箱、木架、托膜、托木(大客户模式下运输方式为零担时必填)
             'smsNotify' => 'N', //短信通知  Y:需要 N: 不需要
             'passwordSigning' => 'N', //是否口令签收 仅适用于快递,Y:需要 N: 不需要;若为Y,必须收货人提供验证码给快递员才能签收,该服务是有偿的,具体费用请让我司收货营业部联系张宁(491407),请慎重使用!
             'uri' => [
@@ -187,17 +187,17 @@ return [
                 'order_locus' => 'http://dpsanbox.deppon.com/sandbox-web/standard-order/newTraceQuery.action',
             ]
         ],
-        'prod'=>[
+        'prod' => [
             'app_key' => 'bb4e6c0b24794795c306b3461f5470d3',
             'company_code' => 'EWBSHBSGYLGLYXGS',
             'customer_Code' => 'F2015082279473065',
             'sign' => 'IYKO',
             'needTraceInfo' => 0, //是否需要订阅轨迹 1:是 2:否
-            'orderType' => [1 => '散客模式',2 => '大客户模式',3 => '同步筛单下单'], //下单模式 1:散客模式 2:大客户模式 3:同步筛单下单
+            'orderType' => [1 => '散客模式', 2 => '大客户模式', 3 => '同步筛单下单'], //下单模式 1:散客模式 2:大客户模式 3:同步筛单下单
             'transportType' => ['JZQY_LONG' => '精准汽运', 'JZKH' => '精准卡航'], //运输方式/产品类型 快递运输方式 : RCP:大件快递360; NZBRH:重包入户; ZBTH:重包特惠; WXJTH:微小件特惠; JJDJ:经济大件; PACKAGE:标准快递; DEAP:特准快件;HKDJC:航空大件次日达; HKDJG:航空大件隔日达; TZKJC:特快专递; 零担运输方式: JZKY:精准空运(仅散客模式支持该运输方式); JZQY_LONG:精准汽运; JZKH:精准卡航; 整车运输方式 1.整车配送 ZCPS 2.精准专车 JZZHC
-            'payType' => [0 => '发货人付款(现付)(大客户模式不支持寄付)',1 => '收货人付款(到付)',2 => '发货人付款(月结)'], //支付方式  0、发货人付款(现付)(大客户模式不支持寄付) 1、收货人付款(到付) 2、发货人付款(月结)
-            'backSignBill' => [0 =>'无需返单',1 => '签收单原件返回',2 => '电子签收单'], //签收回单  0:无需返单 1:签收单原件返回 2:电子签收单(电子签名图片需要另外对接查询接口)
-            'packageService' => ['纸','纤','木箱','木架','托膜','托木'],  //包装(直接用中文) : 纸、纤、木箱、木架、托膜、托木(大客户模式下运输方式为零担时必填)
+            'payType' => [0 => '发货人付款(现付)(大客户模式不支持寄付)', 1 => '收货人付款(到付)', 2 => '发货人付款(月结)'], //支付方式  0、发货人付款(现付)(大客户模式不支持寄付) 1、收货人付款(到付) 2、发货人付款(月结)
+            'backSignBill' => [0 => '无需返单', 1 => '签收单原件返回', 2 => '电子签收单'], //签收回单  0:无需返单 1:签收单原件返回 2:电子签收单(电子签名图片需要另外对接查询接口)
+            'packageService' => ['纸', '纤', '木箱', '木架', '托膜', '托木'],  //包装(直接用中文) : 纸、纤、木箱、木架、托膜、托木(大客户模式下运输方式为零担时必填)
             'smsNotify' => 'N', //短信通知  Y:需要 N: 不需要
             'passwordSigning' => 'N', //是否口令签收 仅适用于快递,Y:需要 N: 不需要;若为Y,必须收货人提供验证码给快递员才能签收,该服务是有偿的,具体费用请让我司收货营业部联系张宁(491407),请慎重使用!
             'uri' => [
@@ -206,4 +206,21 @@ return [
             ]
         ]
     ],
+
+    'collectUpload' => [
+        'ZTO' => [
+            'test' => [
+                'url' => 'https://japi-test.zto.com/zto.network.collectUpload',
+                'x-appKey' => 'c51c718eb899e9f706979',
+                'appSecret' => '9f664e3ab08049874aa417720840161a',
+                'appId' => 'GJWL',
+            ],
+            'prod' =>[
+                'url' => 'https://japi.zto.com/zto.network.collectUpload',
+                'x-appKey' => 'c51c718eb899e9f706979',
+                'appSecret' => '9f664e3ab08049874aa417720840161a',
+                'appId' => '9f664e3ab08049874aa417720840161a',
+            ]
+        ]
+    ]
 ];

+ 4 - 0
config/haiRou.php

@@ -12,4 +12,8 @@ return [
         /* outbound waiting time/second */
         "outBinAwait" => 60,
     ],
+
+    "box" => [
+        "prefix" => ["IDE"],
+    ],
 ];

+ 1 - 1
config/stores.php

@@ -9,6 +9,6 @@ return [
         "宝时" => "BAOSHI",
     ],
     "types" => [
-        'THRK','DBRK','QTRK','HHRK','CGRK'
+        'THRK','DBRK','QTRK','HHRK','CGRK',"F32"
     ]
 ];

+ 0 - 5
resources/views/package/logistic/index.blade.php

@@ -378,7 +378,6 @@
                             ]
                         },
                         {name: 'customer_service_remark_created_at_start', type: 'dateTime', tip: '选择显示客服备注时间的起始时间'},
-
                     ],
                     [
                         {
@@ -409,7 +408,6 @@
                             placeholder: '是否有查询记录',
                             data: [{name: true, value: '是'}, {name: false, value: '否'}]
                         },
-
                         {name: 'sent_at_end', type: 'dateTime', tip: '选择显示发出时间的截止时间'},
                         {
                             name: 'is_issue',
@@ -427,7 +425,6 @@
                             data: [{name: '无', value: '无'}, {name: '有', value: '有'}]
                         },
                         {name: 'customer_service_remark_created_at_end', type: 'dateTime', tip: '选择显示客服备注时间的起始时间'},
-
                     ],
                     [
                         {
@@ -473,8 +470,6 @@
                         },
                         {name: 'default_date', type: 'checkbox', tip: '默认15天', data: [{name: 'ture', value: '默认15天'}]},
                         {name: 'default_logistics', type: 'checkbox', tip: '默认承运商', data: [{name: 'ture', value: '默认承运商'}]},
-
-
                     ]
                 ];
                 _this.form = new query({

+ 30 - 1
resources/views/store/blindReceive/index.blade.php

@@ -15,6 +15,7 @@
                                 <p class="text-muted" style="font-size: 0.5em" v-if="inputMode=='regular'">常规:可输入效期,相同条码记录不会合并</p>
                                 <p class="text-muted" style="font-size: 0.5em" v-if="inputMode=='increasing'">逐一扫描:处理单一重复商品,每扫一次对应隔口总数量自动递增,扫到不同条码会提示</p>
                                 <p class="text-muted" style="font-size: 0.5em" v-if="inputMode=='multiIncreasing'">边扫边分:处理多种商品,自动将扫到的不同条码数量递增到各自隔口号</p>
+                                <p class="text-muted" style="font-size: 0.5em" v-if="inputMode==='sweepModel'">狂扫模式:无间断扫描条码</p>
                                 <ul class="nav nav-tabs mb-4 mt-n3">
                                     <li class="nav-item"><a href="#" class="nav-link" :class="inputMode=='regular'?'active':''"
                                                             @click="inputMode='regular';changeToManualInputAmount();cleanInputs();inputting.fromIncreasing=false">常规</a></li>
@@ -22,6 +23,8 @@
                                                             @click="inputMode='increasing';changeToScanInputAmount();cleanInputs();inputting.fromIncreasing=true;">逐一扫描</a></li>
                                     <li class="nav-item"><a href="#" class="nav-link" :class="inputMode=='multiIncreasing'?'active':''"
                                                             @click="inputMode='multiIncreasing';changeToScanInputAmount();cleanInputs();inputting.fromIncreasing=true">边扫边分</a></li>
+                                    <li class="nav-item"><a href="#" class="nav-link" :class="inputMode==='sweepModel'?'active':''"
+                                                            @click="inputMode='sweepModel';changeToScanInputAmount();cleanInputs();inputting.fromIncreasing=true">狂扫模式</a></li>
                                 </ul>
                             </div>
                             <div class="col-6">
@@ -50,8 +53,13 @@
                                     </div>
                                     <input type="text" class="form-control mb-2" v-model="inputting.unique_code" @focusin="focusOutDocument" @focusout="focusDocument" @keyup="oninputEnter">
                                 </div>
+                                <div v-if="inputMode==='sweepModel'" class="mt-5">
+                                    <label class="text-left font-weight-bold">已扫数量</label>
+                                    <input type="number" id="amount" class="form-control mt-0" placeholder="" :disabled="status.amountDisable"
+                                           v-model="inputting.amount" style='height: 40px;font-size: 1.6em;color:blue;font-weight: bolder;padding: 3px;text-align: center'>
+                                </div>
                             </div>
-                            <div class="col-6">
+                            <div class="col-6" v-if="inputMode!=='sweepModel'">
                                 <div class="card-title" id="amountLabel">
                                     手动输入数量:
                                 </div>
@@ -221,10 +229,31 @@
                             switch(data.inputMode){
                                 case 'increasing': data.commitGoodsOnIncreasingMode();break;
                                 case 'multiIncreasing': data.commitGoodsOnMultiIncreasingMode();break;
+                                case 'sweepModel': data.commitGoodsOnSweepModel();break;
                             }
                         }
                     });
                 },
+                commitGoodsOnSweepModel(){
+                    let repeatedBarcode=this.repeatedIncreasingBarcodeFromSaved();
+                    if(!repeatedBarcode){
+                        this.focusOutDocument();
+                        this.alertVibrate();
+                        this.inputting.amount=1;
+                        this.goodses.unshift(JSON.parse(JSON.stringify(this.inputting)));
+                        window.tempTip.setDuration(500);
+                        window.tempTip.showSuccess('保存成功');
+                        this.focusDocument();
+                        this.audioDing();
+                    }else{
+                        repeatedBarcode.amount++;
+                        this.inputting.amount=repeatedBarcode.amount;
+                        window.tempTip.setDuration(500);
+                        window.tempTip.showSuccess(repeatedBarcode.amount);
+                        this.focusDocument();
+                        this.audioDing();
+                    }
+                },
                 commitGoodsOnIncreasingMode: function () {
                     let data = this;
                     function doIt(){

+ 455 - 0
resources/views/storeOut/storeOutReview/index.blade.php

@@ -0,0 +1,455 @@
+@extends('layouts.app')
+@section('title','出库复核')
+@section('head')
+    <style>
+        /*查询容器*/
+        .select-wrapper {
+            margin: 30px 20px;
+            width: 100%;
+            height: 50px;
+            font-size: 32px;
+            line-height: 50px;
+        }
+
+        .select-wrapper > div {
+            float: left;
+            margin-left: 30px;
+        }
+
+        table {
+            margin: 10px;
+            width: 100%;
+            border-collapse: collapse;
+            border-spacing: 0;
+            table-layout: auto;
+            vertical-align: text-top;
+            border: rgb(245, 245, 245) solid 1px;
+        }
+
+        /*表头*/
+        table .header {
+            background-color: rgb(250, 250, 250);
+            font-weight: bold;
+            font-size: 16px;
+            position: -webkit-sticky;
+            position: sticky;
+            top: 10px;
+        }
+
+        /*table .body .action .more-action {*/
+
+        /*}*/
+
+        table .body .action .more-action:focus + .more-action-list {
+            display: block !important;
+            /*background-color: red;*/
+        }
+
+        table .body .action .more-action + .more-action-list {
+            display: none;
+            position: absolute;
+            margin-left: 50px;
+        }
+
+        table .body .action .more-action-list .more-action-item {
+            display: block;
+        }
+
+        table tr {
+            border-bottom: rgb(239, 239, 239) solid 1px;
+        }
+
+        .info-wrapper {
+            min-width: 768px;
+            overflow: hidden;
+        }
+
+        .commodity-all-wrapper {
+            max-height: 300px;
+            margin-bottom: 10px;
+            overflow: scroll;
+        }
+
+        .commodity-all-wrapper::-webkit-scrollbar {
+            width: 0;
+        }
+
+        .reviewed-commodity-wrapper {
+            max-height: 300px;
+            margin-bottom: 10px;
+        }
+
+        .reviewed-commodity-wrapper .commodity-list-wrapper {
+            float: left;
+            width: 70%;
+            height: 380px;
+
+        }
+
+        /*新箱号*/
+        .reviewed-commodity-wrapper .commodity-list-wrapper .new-box-wrapper {
+            height: 80px;
+        }
+
+        .new-box-wrapper label {
+            line-height: 80px;
+            margin-left: 50px;
+            font-size: 30px;
+            font-weight: bold;
+        }
+
+        .new-box-wrapper input {
+            font-size: 30px;
+        }
+
+        .new-box-wrapper button {
+            font-size: 25px;
+            margin-left: 20px;
+            margin-bottom: 12px;
+        }
+
+        .reviewed-commodity-wrapper .commodity-list-wrapper .commodity-list {
+            overflow: scroll;
+            height: 300px;
+        }
+
+        .reviewed-commodity-wrapper .commodity-list-wrapper .commodity-list::-webkit-scrollbar {
+            width: 0;
+        }
+
+        .reviewed-commodity-wrapper .commodity-info {
+            float: left;
+            width: 30%;
+        }
+
+        .commodity-info .info-item {
+            font-size: 18px;
+            width: 100%;
+            display: block;
+            margin: 5px 0;
+        }
+
+        .commodity-info .info-item label {
+            display: inline-block;
+            width: 100px;
+            text-align: right;
+        }
+
+        .commodity-info .info-item input {
+            vertical-align: top;
+
+        }
+
+        .review-status-wrapper {
+            height: 75px;
+            margin-bottom: 10px;
+        }
+
+        .review-status-wrapper .review-status-item {
+
+        }
+
+        .review-status-wrapper .review-status-item .description {
+            font-size: 16px;
+        }
+
+        .review-status-wrapper .review-status-item .commodity-total-number,
+        .review-status-wrapper .review-status-item .commodity-packed-number,
+        .review-status-wrapper .review-status-item .commodity-unpacked-number,
+        .review-status-wrapper .review-status-item .commodity-scan-number {
+            font-size: 30px;
+            font-weight: bold;
+            display: inline-block;
+            width: 100px;
+            height: 35px;
+            line-height: 35px;
+            text-align: center;
+            margin-top: 20px;
+            margin-left: 20px;
+        }
+
+        .review-status-wrapper .review-status-item .commodity-total-number {
+            background-color: rgb(235, 199, 13);
+        }
+
+        .review-status-wrapper .review-status-item .commodity-packed-number {
+            background-color: rgb(118, 191, 226);
+        }
+
+        .review-status-wrapper .review-status-item .commodity-unpacked-number {
+            background-color: rgb(237, 9, 9);
+        }
+
+        .review-status-wrapper .review-status-item .commodity-scan-number {
+            background-color: rgb(25, 230, 48);
+        }
+
+        .button-list {
+            height: 75px;
+            margin-bottom: 10px;
+        }
+
+        .button-list button {
+            float: left;
+            margin: 3px 25px;
+            width: 100px;
+        }
+    </style>
+@stop
+@section('content')
+    @include('shared._messages')
+    @include('shared._error')
+    <div id="list" class="d-none">
+        <div class="container-fluid">
+            <div class="info-wrapper">
+                <div class="select-wrapper">
+                    <div class="input-wrapper">
+                        <label for="orderno">订单号:</label>
+                        <input autofocus @keydown.enter="apiGetOrderDetail()" type="text" id="orderno"
+                               v-model="selectParameters.orderno">
+                    </div>
+                    <div class="input-wrapper">
+                        <label for="waveno">波次号:</label>
+                        <input @keydown.enter="apiGetOrderDetail()" type="text" id="waveno"
+                               v-model="selectParameters.waveno">
+                    </div>
+                    <div class="input-wrapper">
+                        <label for="expressno">快递单号:</label>
+                        <input @keydown.enter="apiGetOrderDetail()" type="text" id="expressno"
+                               v-model="selectParameters.expressno">
+                    </div>
+                    <div class="btn-wrapper">
+                        <button @click="apiGetOrderDetail()" type="button" class="btn btn-primary btn-lg"
+                                id="btn-search">查询
+                        </button>
+                        <button @click="clearSelectParameters()" type="button" class="btn btn-primary btn-lg">清除
+                        </button>
+                    </div>
+                </div>
+                <div class="commodity-all-wrapper">
+                    <table class="table  table-bordered table-hover">
+                        <tr class="header">
+                            <td>行号</td>
+                            <td>产品代码</td>
+                            <td>中文描述</td>
+                            <td>状态</td>
+                            <td>装箱</td>
+                            <td>分配数</td>
+                            <td>复核数</td>
+                            <td>未复核数</td>
+                            <td>质量状态</td>
+                            <td>备注</td>
+                            <td>拣货库位</td>
+                            <td>英文描述</td>
+                            <td>产品条码</td>
+                            <td>操作</td>
+                        </tr>
+                        <tr v-for="(v,k) of orderDetails" @click="clickCurrentDetail(v)">
+                            <td>@{{ k+1 }}</td> {{--行号--}}
+                            <td>@{{ v.sku }}</td> {{--产品代码--}}
+                            <td>@{{ v.skudescrc }}</td> {{--中文描述--}}
+                            <td>@{{ v.status_name }}</td> {{--状态--}}
+                            <td>@{{ v.packflag }}</td> {{--装箱--}}
+                            <td>@{{ v.qty }}</td> {{--分配数--}}
+                            <td>@{{ v.packedqty }}</td> {{--复核数--}}
+                            <td>@{{ v.qty - v.packedqty }}</td> {{--未复核数--}}
+                            <td>@{{ v.lotatt08 }}</td> {{--质量状态--}}
+                            <td>-</td> {{--备注--}}
+                            <td>@{{ v.location }}</td> {{--拣货库位--}}
+                            <td>@{{ v.sku }}</td> {{--英文描述--}}
+                            <td>@{{ v.alternate_sku1 }}</td> {{--产品条码--}}
+                            <td>操作1 更多</td> {{--操作 --}}
+                        </tr>
+
+                    </table>
+                </div>
+                <div class="reviewed-commodity-wrapper">
+                    <div class="commodity-list-wrapper">
+                        <!--新箱号-->
+                        <div class="new-box-wrapper">
+                            <label for="new-box-number">新箱号: </label>
+                            <input type="text" class="new-box-input" id="new-box-number">
+                            <button class="btn btn-info">清除</button>
+                        </div>
+                        <div class="commodity-list">
+                            <table>
+                                <tr class="header">
+                                    <td>产品代码</td>
+                                    <td>中文描述</td>
+                                    <td>英文描述</td>
+                                    <td>数量</td>
+                                    <td>操作</td>
+                                </tr>
+
+                                <tr class="body" v-for="(v,k) of reviewedSkus">
+                                    <td>@{{ v.sku }}</td>
+                                    <td>@{{ v.skudescrc }}</td>
+                                    <td>@{{ v.sku }}</td>
+                                    <td>@{{ v.inputQty }}</td>
+                                    <td class="action">
+                                        <a href="javascript:;">操作1</a>
+                                    </td>
+                                </tr>
+                            </table>
+                        </div>
+                    </div>
+                    <div class="commodity-info">
+                        <div class="info-item">
+                            <label for="commodity-code">产品编码: </label>
+                            <input type="text" id="commodity-code" v-model="currentDetail.alternate_sku1">
+                        </div>
+                        <div class="info-item">
+                            <label for="amount">数量: </label>
+                            <input @keydown.enter="reviewSku()" type="number" id="amount" v-model="currentDetail.qty">
+                        </div>
+                        <div class="info-item">
+                            <label for="unit">单位: </label>
+                            <input disabled="true" type="text" id="unit" v-model="currentDetail.uom">
+                        </div>
+                    </div>
+                </div>
+                <div class="review-status-wrapper row col-8">
+                    <div class="review-status-item col">
+                        <span class="description">产品总数</span>
+                        <span class="commodity-total-number">@{{ reviewStatus.qty }}</span>
+                    </div>
+                    <div class="review-status-item col">
+                        <span class="description">已装箱数</span>
+                        <span class="commodity-packed-number">@{{ reviewStatus.packedqty }}</span>
+                    </div>
+                    <div class="review-status-item col">
+                        <span class="description">未装箱数</span>
+                        <span class="commodity-unpacked-number">@{{ reviewStatus.unpackedqty }}</span>
+                    </div>
+                    <div class="review-status-item col">
+                        <span class="description">扫描数量</span>
+                        <span class="commodity-scan-number">@{{ reviewStatus.scanedqty }}</span>
+                    </div>
+                </div>
+                <div class="button-list">
+                    <button class="btn btn-info">装箱完成</button>
+                    <button class="btn btn-info">打印装箱单</button>
+                    <button class="btn btn-info">装箱标签</button>
+                    <button class="btn btn-info">确定</button>
+                </div>
+            </div>
+        </div>
+    </div>
+@endsection
+@section('lastScript')
+    <script>
+        let vue = new Vue({
+            el: "#list",
+            data: {
+                selectParameters: {
+                    orderno: '',
+                    waveno: '',
+                    expressno: ''
+                },
+                orderDetails: [],
+                currentDetail: {
+                    alternate_sku1: null,
+                    qty: 1,
+                    uom: null,
+                },
+                reviewStatus: {
+                    qty: 0,
+                    packedqty: 0,
+                    unpackedqty: 0,
+                    scanedqty: 0,
+                },
+                reviewedSkus: []
+            },
+            created() {
+
+            },
+            mounted() {
+                $('#list').removeClass('d-none');
+            },
+            methods: {
+                apiGetOrderDetail() {
+                    //查询条件不能为空
+                    let preg = '[a-zA-z0-9]+';//包含任意字母,数字
+                    if (
+                        (!this.selectParameters.orderno.match(preg)) &&
+                        (!this.selectParameters.waveno.match(preg)) &&
+                        (!this.selectParameters.expressno.match(preg))
+                    ) {
+                        tempTip.setDuration(3000);
+                        tempTip.show("查询条件不能为空");
+                        return;
+                    }
+                    //拼接查询条件
+                    let url = '{{ url('apiLocal/storeOut/storeOutReview/apiGetOrderDetail/?') }}';
+                    if (this.selectParameters.orderno.match(preg)) {
+                        url += ("orderno=" + this.selectParameters.orderno.trim());
+                    } else if (this.selectParameters.waveno.match(preg)) {
+                        url += ("waveno=" + this.selectParameters.waveno.trim());
+                    } else if (this.selectParameters.expressno.match(preg)) {
+                        url += ("expressno=" + this.selectParameters.expressno.trim());
+                    }
+                    document.getElementById('btn-search').disabled = true;
+                    tempTip.setDuration(2000);
+                    tempTip.showSuccess('查询中请稍后!');
+                    axios.get(url).then(res => {
+                        if (res.data.success) {
+                            tempTip.setDuration(2000);
+                            tempTip.showSuccess('成功!');
+                            /*orderDetails 赋值*/
+                            this.orderDetails = res.data.data;
+                            /*reviewStatus 赋值*/
+                            this.reviewStatus.qty = this.orderDetails.reduce((sum, item) => sum + Number(item.qty), 0);
+                            this.reviewStatus.packedqty = this.orderDetails.reduce((sum, item) => sum + Number(item.packedqty), 0);
+                            this.reviewStatus.packedqty = this.reviewStatus.qty - this.reviewStatus.packedqty;
+                            /*产品编码自动获取焦点*/
+                            document.getElementById('commodity-code').focus();
+                        }
+                        document.getElementById('btn-search').disabled = false;
+                    }).catch(err => {
+                        document.getElementById('btn-search').disabled = false;
+                        tempTip.setDuration(2000);
+                        tempTip.show('系统异常' + err);
+                    });
+                },
+                /*清空查询输入*/
+                clearSelectParameters() {
+                    this.selectParameters.orderno = '';
+                    this.selectParameters.waveno = '';
+                    this.selectParameters.expressno = '';
+                },
+                /*点击选中商品*/
+                clickCurrentDetail(currentDetail) {
+                    this.currentDetail.alternate_sku1 = currentDetail.alternate_sku1;
+                    this.currentDetail.uom = currentDetail.uom;
+                    document.getElementById('amount').focus();
+                },
+                reviewSku() {
+                    //查询输入的产品编码
+                    let selectedSkuIndex = this.orderDetails.findIndex(item => {
+                        return item.alternate_sku1 === this.currentDetail.alternate_sku1;
+                    });
+                    console.log(selectedSkuIndex);
+                    //添加inputQty属性
+                    if (selectedSkuIndex !== -1) this.orderDetails[selectedSkuIndex].inputQty = this.currentDetail.qty;
+
+                    if (this.currentDetail.qty === 0) {
+                        tempTip.setDuration(2000);
+                        tempTip.show('数量不能为0!');
+                    } else if (selectedSkuIndex === -1) {
+                        tempTip.setDuration(2000);
+                        tempTip.show('输入产品编码有误!');
+                    } else if (this.currentDetail.qty > (this.orderDetails[selectedSkuIndex].qty - this.orderDetails[selectedSkuIndex].packedqty)) {
+                        tempTip.setDuration(2000);
+                        tempTip.show('输入数量不能大于未复核数!');
+                    } else {
+                        this.reviewedSkus.unshift(this.orderDetails[selectedSkuIndex]);//添加到头部
+                        tempTip.setDuration(2000);
+                        tempTip.showSuccess('成功!');
+                        this.orderDetails.splice(selectedSkuIndex, 1);
+                    }
+                }
+            },
+            filters: {},
+        });
+    </script>
+@endsection

+ 7 - 0
routes/apiLocal.php

@@ -269,3 +269,10 @@ Route::prefix('workOrder')->group(function(){
     Route::post('batchUpdateIssueType','WorkOrderController@batchUpdateIssueTypeApi')->name('workOrder.batchUpdateIssueTypeApi'); // 修改问题类型
     Route::delete('/{id}','WorkOrderController@destroyApi')->name('workOrder.destroyApi');
  });
+/*出库*/
+Route::group(['prefix'=>'storeOut'],function(){
+    /*复核*/
+    Route::group(['prefix'=>'storeOutReview'], function () {
+        Route::get('apiGetOrderDetail', 'StoreOutReviewController@apiGetOrderDetail')->name('StoreOutReview.apiGetOrderDetail');
+    });
+});

+ 6 - 0
routes/web.php

@@ -1038,5 +1038,11 @@ Route::group(['prefix'=>'package'],function(){
         Route::post('{requirement}/status','RequirementController@status')->name('requirements.status');
     });
 
+    Route::group(['prefix'=>'storeOut'],function(){
+        Route::group(['prefix'=>'storeOutReview'], function () {
+            Route::get('/', 'StoreOutReviewController@index')->name('StoreOutReview.index');
+        });
+    });
+
 });
 

+ 1 - 1
tests/Feature/LogisticZopSyncTest.php

@@ -39,7 +39,7 @@ class LogisticZopSyncTest extends TestCase
 
     public function test_get()
     {
-        LogisticZopSync::dispatch('75497969890714');
+        LogisticZopSync::dispatch('75502471791896');
     }
 
 

+ 1 - 1
tests/Services/LogisticSFSync/HandleTest.php

@@ -30,7 +30,7 @@ class HandleTest extends TestCase
      */
     public function handle_test()
     {
-//        LogisticSFSync::dispatch('SF1333381646256');
+        LogisticSFSync::dispatch('SF1320174725157');
         $this->assertTrue(true);
     }
 }