浏览代码

Merge branch 'yang-package' into yang

ANG YU 4 年之前
父节点
当前提交
4ec8e79232
共有 62 个文件被更改,包括 1817 次插入736 次删除
  1. 0 1
      app/Commodity.php
  2. 42 0
      app/Console/Commands/AccordingToOwnersManualBack.php
  3. 2 2
      app/DeliveryAppointment.php
  4. 59 23
      app/Filters/OrderPackageFilters.php
  5. 6 0
      app/Filters/WorkOrderFilters.php
  6. 19 17
      app/Http/Controllers/DeliveryAppointmentController.php
  7. 7 1
      app/Http/Controllers/HandInStorageController.php
  8. 2 0
      app/Http/Controllers/MeasureMonitorController.php
  9. 27 0
      app/Http/Controllers/OrderController.php
  10. 14 5
      app/Http/Controllers/PackageLogisticController.php
  11. 186 54
      app/Http/Controllers/TestController.php
  12. 38 32
      app/Http/Controllers/WaybillController.php
  13. 9 0
      app/Http/Controllers/WorkOrderController.php
  14. 3 9
      app/Http/Controllers/api/thirdPart/haiq/StorageController.php
  15. 5 5
      app/Http/Requests/GateRequest.php
  16. 1 0
      app/Jobs/LogisticYTOSync.php
  17. 4 4
      app/Jobs/LogisticZopSync.php
  18. 1 1
      app/OracleDOCASNHeader.php
  19. 3 2
      app/OracleIdxAsrsReceive.php
  20. 10 1
      app/OrderIssue.php
  21. 55 26
      app/OrderPackage.php
  22. 16 7
      app/Services/HandInStorageService.php
  23. 0 3
      app/Services/LogisticAliJiSuApiService.php
  24. 6 13
      app/Services/LogisticSFService.php
  25. 3 1
      app/Services/LogisticYDService.php
  26. 1 3
      app/Services/LogisticYTOService.php
  27. 5 2
      app/Services/LogisticZopService.php
  28. 27 9
      app/Services/MaterialBoxService.php
  29. 8 0
      app/Services/OrderIssueService.php
  30. 39 30
      app/Services/OrderPackageReceivedSyncService.php
  31. 168 83
      app/Services/OrderPackageService.php
  32. 43 5
      app/Services/OrderService.php
  33. 1 0
      app/Services/OwnerPriceOperationService.php
  34. 2 13
      app/Services/StoreItemService.php
  35. 4 15
      app/Services/StoreService.php
  36. 34 30
      app/Services/WorkOrderService.php
  37. 0 14
      app/StoreItem.php
  38. 140 0
      app/Traits/LogisticSyncTrait.php
  39. 0 14
      app/WorkOrder.php
  40. 28 11
      config/api_logistic.php
  41. 15 0
      config/database.php
  42. 4 7
      database/factories/OrderPackageFactory.php
  43. 32 0
      database/migrations/2021_09_06_095009_change_column_to_work_orders.php
  44. 32 0
      database/migrations/2021_09_06_135431_add_is_intercept_to_order_issues.php
  45. 34 0
      database/migrations/2021_09_09_154053_add_column_exception_type_to_order_packages_table.php
  46. 42 0
      database/migrations/2021_09_11_142547_add_index_to_order_packages_table.php
  47. 42 0
      database/migrations/2021_09_11_163234_add_index_created_at_to_order_packages_table.php
  48. 1 0
      resources/views/maintenance/user/create.blade.php
  49. 91 2
      resources/views/order/index/delivering.blade.php
  50. 7 1
      resources/views/order/issue/index.blade.php
  51. 58 23
      resources/views/order/workOrder/index.blade.php
  52. 98 32
      resources/views/package/logistic/index.blade.php
  53. 15 139
      resources/views/store/deliveryAppointment/list.blade.php
  54. 0 1
      resources/views/store/handInStorage/receiveDetailPage.blade.php
  55. 2 2
      resources/views/store/inStorage/storeItem.blade.php
  56. 47 55
      resources/views/transport/waybill/delivering.blade.php
  57. 41 37
      resources/views/transport/waybill/index.blade.php
  58. 1 0
      routes/apiLocal.php
  59. 1 0
      routes/web.php
  60. 1 1
      tests/Feature/LogisticZopSyncTest.php
  61. 207 0
      tests/Services/LogisticSFService/SetExceptionStatusTest.php
  62. 28 0
      tests/Services/LogisticYTSync/SyncTest.php

+ 0 - 1
app/Commodity.php

@@ -15,7 +15,6 @@ class Commodity extends Model
     use ModelTimeFormat;
     protected $fillable=['name','sku','owner_id','created_at','length',
         'width','height','volumn',"type","pack_spec",'updated_at',"remark"];
-    //protected $appends=['barcode']; N+1隐患 暂时干掉
 
     public function model():HasOne
     {

+ 42 - 0
app/Console/Commands/AccordingToOwnersManualBack.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+
+class AccordingToOwnersManualBack extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'AccordingToOwnersManualBack';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '根据货主自动回传奇门标记';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        return 0;
+    }
+}

+ 2 - 2
app/DeliveryAppointment.php

@@ -35,13 +35,13 @@ class DeliveryAppointment extends Model
     const PERIOD=[
         0 => "09-11",
         1 => "12-14",
-        2 => "14-17",
+        2 => "14-18",
     ];
     //时长 映射PERIOD常量
     const HOUR=[
         0 => 3,
         1 => 3,
-        2 => 4,
+        2 => 5,
     ];
     //状态
     const STATUS=[

+ 59 - 23
app/Filters/OrderPackageFilters.php

@@ -18,25 +18,29 @@ 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',//是否有客服备注
+        'customer_service_remark_created_at_start',//客服备注起始时间
+        'customer_service_remark_created_at_end',//客服备注截止时间
     ];
 
     protected $orderIssueQuery;
@@ -81,9 +85,11 @@ class OrderPackageFilters
     private function has_transfer_status($has_transfer_status)
     {
         if ($has_transfer_status == '是') {
-            $this->queryBuilder->whereNotNull('transfer_status');
+            $this->queryBuilder->whereNotNull('transfer_status')->where('transfer_status', '!=', []);
         } elseif ($has_transfer_status == '否') {
-            $this->queryBuilder->whereNull('transfer_status');
+            $this->queryBuilder->where(function ($query) {
+                $query->whereNull('transfer_status')->orwhere('transfer_status', []);
+            });
         }
     }
 
@@ -128,17 +134,17 @@ class OrderPackageFilters
 
     private function sent_at_start($sent_at_start)
     {
-        $this->queryBuilder->where('sent_at', '>=', Carbon::parse($sent_at_start)->startOfDay());
+        $this->queryBuilder->where('created_at', '>=', Carbon::parse($sent_at_start)->startOfDay());
     }
 
     private function sent_at_end($sent_at_end)
     {
-        $this->queryBuilder->where('sent_at', '<=', Carbon::parse($sent_at_end)->endOfDay());
+        $this->queryBuilder->where('created_at', '<=', Carbon::parse($sent_at_end)->endOfDay());
     }
 
     public function default_date()
     {
-        $this->queryBuilder->where('sent_at', '>=', now()->startOfDay()->subDays(15))->where('sent_at', '<', now()->startOfDay()->addDay());
+        $this->queryBuilder->where('created_at', '>=', now()->startOfDay()->subDays(15))->where('created_at', '<', now()->startOfDay()->addDay());
     }
 
     public function default_logistics()
@@ -212,4 +218,34 @@ class OrderPackageFilters
             $query->from('orders')->select('order_id')->whereIn('code', $ordernos);
         });
     }
+
+    public function exception_status($exception_status)
+    {
+        $arr = array_filter(preg_split('/[,, ]+/is', $exception_status));
+        $this->queryBuilder->whereIn('exception_status', $arr);
+    }
+
+    public function is_customer_service_remark($is_customer_service_remark)
+    {
+        if ($is_customer_service_remark === '是') {
+            $this->queryBuilder->has('orderPackageRemarks');
+        } else if ($is_customer_service_remark === '否') {
+            $this->queryBuilder->doesntHave('orderPackageRemarks');
+        }
+    }
+
+    public function customer_service_remark_created_at_start($customer_service_remark_created_at_start)
+    {
+        $this->queryBuilder->whereIn('id', function ($query) use ($customer_service_remark_created_at_start) {
+            return $query->from('order_package_remarks')->select('order_package_id')->where('created_at', '>=', $customer_service_remark_created_at_start);
+        });
+    }
+
+
+    public function customer_service_remark_created_at_end($customer_service_remark_created_at_end)
+    {
+        $this->queryBuilder->whereIn('id', function ($query) use ($customer_service_remark_created_at_end) {
+            return $query->from('order_package_remarks')->select('order_package_id')->where('created_at', '<=', $customer_service_remark_created_at_end);
+        });
+    }
 }

+ 6 - 0
app/Filters/WorkOrderFilters.php

@@ -6,11 +6,13 @@ namespace App\Filters;
 use App\Order;
 use App\OrderIssue;
 use App\OrderPackage;
+use App\Services\OwnerService;
 use App\Traits\ModelSearchWay;
 use App\User;
 use App\WorkOrder;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
 
 class WorkOrderFilters
 {
@@ -66,6 +68,10 @@ class WorkOrderFilters
     {
         if(isset($this->params['data']))
             $this->id(explode(',',$this->params['data']));
+
+        if (!isset($this->params['owner'])){
+            $this->getOrderQuery()->whereIn('owner_id', app('UserService')->getPermittingOwnerIds(Auth::user())??[]);
+        }
     }
 
     public function beforeApply()

+ 19 - 17
app/Http/Controllers/DeliveryAppointmentController.php

@@ -529,24 +529,18 @@ html;
         if (!$number)return ["status"=>417];
         $period = app("DeliveryAppointmentService")->getPeriod();
         if ($period===false)return ["status"=>416]; //非法时段扫码
-        $mark = false;
-        mark:
-        $car = DeliveryAppointmentCar::query()->whereNull("delivery_time")->where("status",0)
+        $car = DeliveryAppointmentCar::query()->with("deliveryAppointment")->whereNull("delivery_time")->where("status",0)
             ->where("appointment_number",$number)->whereHas("deliveryAppointment",function (Builder $query)use($period){
-                $query->where("appointment_date",date("Y-m-d"))
-                ->where("date_period",$period)->whereIn("status",[0,3]);
+                $query->whereIn("status",[0,3]);
             })->first();
-        if (!$car && $period===1){$period = 0;$mark = true;goto mark;}
-        if ($mark && $car){
-            $car->load("deliveryAppointment");
-            $available = app("DeliveryAppointmentService")->getAvailableCapacity($car->deliveryAppointment->appointment_date,$car->deliveryAppointment->date_period,$car->deliveryAppointment->warehouse_id);
-            if ($available<$car->deliveryAppointment->capacity)$car = null;
-        }
-        if (!$car)return ["status"=>417];
+        if (!$car || !$car->deliveryAppointment)return ["status"=>417];
         $car->update(["delivery_time"=>date("Y-m-d H:i:s"),"status"=>1]);
-        /** @var DeliveryAppointmentCar $car */
-        if ($mark)DeliveryAppointment::query()->where("id",$car->delivery_appointment_id)->update(["status" => 0]);
-        else event(new DeliveryAppointmentEvent($car));
+        if (Carbon::now()->gt(Carbon::parse($car->deliveryAppointment->appointment_date." ".explode("-",DeliveryAppointment::PERIOD[$car->deliveryAppointment->date_period])[1].":00:00"))){
+            $available = app("DeliveryAppointmentService")->getAvailableCapacity(date("Y-m-d"),$period,$car->deliveryAppointment->warehouse_id);
+            if ($available<$car->deliveryAppointment->capacity)return ["status"=>417];
+            DeliveryAppointment::query()->where("id",$car->delivery_appointment_id)->update(["status" => 0]);
+        }
+        event(new DeliveryAppointmentEvent($car));
         return ["status"=>200,"k"=>$car->delivery_appointment_id];
     }
 
@@ -571,7 +565,8 @@ html;
         /** @var DeliveryAppointmentCar|\stdClass $car */
         $car = DeliveryAppointmentCar::query()->with("deliveryAppointment")->where("status",1)->find(request("id"));
         if (!$car || !$car->deliveryAppointment)$this->error("单据不存在");
-        if ($car->deliveryAppointment->appointment_date!=date('Y-m-d'))$this->error("禁止越天逾期操作");
+        if (!$car->delivery_time)$this->error("尚未签到");
+        if (mb_substr($car->delivery_time,0,10)!=date('Y-m-d'))$this->error("禁止越天逾期操作");
         $car->update(["status"=>2]);
         $status = app("DeliveryAppointmentService")->checkFull($car->delivery_appointment_id);
         event(new DeliveryAppointmentEvent($car));
@@ -585,12 +580,19 @@ html;
     {
         $this->gate("入库管理-入库预约-预约管理-签到");
         if (!request("id"))$this->error("非法参数");
+        $period = app("DeliveryAppointmentService")->getPeriod();
+        if ($period===false)$this->error("当前非工作时间,请在指定时间内送货");
         /** @var DeliveryAppointmentCar|\stdClass $car */
         $car = DeliveryAppointmentCar::query()->whereHas("deliveryAppointment",function (Builder $query){
-            $query->where("appointment_date",date("Y-m-d"));
+            $query->whereIn("status",[0,3]);
         })->find(request("id"));
         if (!$car || !$car->deliveryAppointment)$this->error("单据不存在");
         $car->update(["status"=>1,"delivery_time"=>date("Y-m-d H:i:s")]);
+        if (Carbon::now()->gt(Carbon::parse($car->deliveryAppointment->appointment_date." ".explode("-",DeliveryAppointment::PERIOD[$car->deliveryAppointment->date_period])[1].":00:00"))){
+            $available = app("DeliveryAppointmentService")->getAvailableCapacity(date("Y-m-d"),$period,$car->deliveryAppointment->warehouse_id);
+            if ($available<$car->deliveryAppointment->capacity)$this->error("仓库产能不足,请另择日期送货");
+            DeliveryAppointment::query()->where("id",$car->delivery_appointment_id)->update(["status" => 0]);
+        }
         event(new DeliveryAppointmentEvent($car));
         $this->success();
     }

+ 7 - 1
app/Http/Controllers/HandInStorageController.php

@@ -3,11 +3,11 @@
 namespace App\Http\Controllers;
 
 use App\Components\AsyncResponse;
-use App\OracleDOCASNDetail;
 use App\OracleDOCASNHeader;
 use App\Services\HandInStorageService;
 use Carbon\Carbon;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
 
 class HandInStorageController extends Controller
 {
@@ -81,12 +81,15 @@ class HandInStorageController extends Controller
      */
     public function getBasSkuWithLot(Request $request): array
     {
+        $start=microtime(true);
         $customerid= $request->input('customerid');
         $skuOrBarcode= $request->input('sku');
         $asnno= $request->input('asnno');
         $asnDetail=app('HandInStorageService')->getAsnDetail($asnno,$skuOrBarcode);
         if (!$asnDetail)$this->error('无效条码');
         $basSku =app('HandInStorageService')->getBasSkuLotId($customerid,$asnDetail->sku);
+        $end=microtime(true);
+        if(($end-$start)>1)Log::warning('手持条码获取详情超时',$request->all());
         if (isset($basSku)&&isset($asnDetail))return ['success'=>true,'basSku'=>$basSku,'asnDetail'=>$asnDetail];
         else $this->error('无效条码');
     }
@@ -97,6 +100,7 @@ class HandInStorageController extends Controller
      */
     public function fluxHandIn(Request $request)
     {
+        $start=microtime(true);
         $this->gate("入库管理-手持入库-收货");
         $info=$request->input('info');
         if ($info['lotatt02']&&Carbon::now()->gt($info['lotatt02']))$this->error('失效日期超过入库效期');
@@ -119,6 +123,8 @@ class HandInStorageController extends Controller
             $result = $handInStorageService->fluxHandIn($info);
             if ($result){
                 $asnQty=$handInStorageService->getAsnQty($info['asnno']);
+                $end=microtime(true);
+                if(($end-$start)>2)Log::warning('手持收货超时',$request->all());
                 $this->success($asnQty);
             } else $this->error("收货失败");
         } catch (\Exception $e) {

+ 2 - 0
app/Http/Controllers/MeasureMonitorController.php

@@ -41,9 +41,11 @@ class MeasureMonitorController extends Controller
     public function speech(Request $request,MeasureMonitorService $service): array
     {
         if (app('WorkOrderService')->isIntercept($request['logistic_number'])){
+            app('OrderIssueService')->intercept($request['logistic_number']);
             return $service->getMp3Audio('拦截订单');
         }
         if ( app('OrderIssueService')->isExists($request['logistic_number'])){
+            app('OrderIssueService')->intercept($request['logistic_number']);
             return $service->getMp3Audio('拦截订单');
         }
         return $service->getMp3Audio($request->input('logistic'));

+ 27 - 0
app/Http/Controllers/OrderController.php

@@ -16,6 +16,7 @@ use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 use Oursdreams\Export\Export;
+use PhpParser\Node\Stmt\DeclareDeclare;
 
 class OrderController extends Controller
 {
@@ -352,4 +353,30 @@ sql;
         }
     }
 
+    /**
+     * @param Request $request
+     * @return array
+     * 一键回传功能
+     */
+    public function manualBack(Request $request): array
+    {
+        if(!Gate::allows('订单管理-订单-一键回传'))return["success"=>false,"data"=>"无权操作"];
+        /** @var OrderService $orderService */
+        $orderService=app(OrderService::class);
+        $orderNos=$request->input('ordernos');
+        $failNo=array();
+        $successNo=array();
+        foreach ($orderNos as $no){
+            $res=$orderService->manualBack($no);
+            if (!$res){
+                array_push($failNo,$no);
+                app('LogService')->log(__METHOD__,'人工回传失败'.__FUNCTION__,json_encode($no),Auth::user()['id']);
+            }else{
+                array_push($successNo,$no);
+            }
+        }
+        if (count($orderNos)>=count($failNo))return ["success"=>true,"successNo"=>$orderNos,"failNo"=>$failNo];
+        else return ["success"=>false,"failNo"=>$failNo];
+    }
+
 }

+ 14 - 5
app/Http/Controllers/PackageLogisticController.php

@@ -70,11 +70,20 @@ class PackageLogisticController extends Controller
 
     public function batchUpdate(Request $request)
     {
-        OrderPackage::query()->whereIn('logistic_number', $request->input('logistic_numbers'))->update([
-            'status' => OrderPackage::switchStatus($request->input('status')),
-            //标记为手动更新
-            'is_manual_update' => true,
-        ]);
+        if (!empty($request->input('status'))) {
+            OrderPackage::query()->whereIn('logistic_number', $request->input('logistic_numbers'))->update([
+                'status' => OrderPackage::switchStatus($request->input('status')),
+                //标记为手动更新
+                'is_manual_update' => true,
+            ]);
+        }else if (!empty($request->input('exceptionStatus'))) {
+            OrderPackage::query()->whereIn('logistic_number', $request->input('logistic_numbers'))->update([
+                'exception_status' => OrderPackage::switchExceptionStatus($request->input('exceptionStatus')),
+                //标记为手动更新
+                'is_manual_update' => true,
+            ]);
+        }
+
     }
 
     /**

+ 186 - 54
app/Http/Controllers/TestController.php

@@ -18,9 +18,16 @@ use App\Jobs\OrderCreateWaybill;
 use App\Jobs\SettlementBillReportTask;
 use App\Jobs\StoreCreateInstantBill;
 use App\Jobs\WeightUpdateInstantBill;
+use App\LaborReport;
+use App\LaborReportStatus;
 use App\MaterialBox;
 use App\MaterialBoxModel;
+use App\OracleDOCASNHeader;
+use App\OracleDOCOrderHeader;
+use App\OracleDocOrderPackingSummary;
 use App\Order;
+use App\OrderIssue;
+use App\OrderIssueProcessLog;
 use App\OrderPackage;
 use App\Owner;
 use App\OwnerFeeDetail;
@@ -38,6 +45,7 @@ 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;
@@ -61,6 +69,8 @@ use App\Waybill;
 use App\WorkOrder;
 use Carbon\Carbon;
 use Carbon\CarbonPeriod;
+use Decimal\Decimal;
+use Doctrine\DBAL\Exception;
 use Firebase\JWT\JWT;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Foundation\Http\FormRequest;
@@ -75,6 +85,7 @@ use Illuminate\Support\Facades\URL;
 use Illuminate\Support\Facades\Validator;
 use Illuminate\Support\Str;
 use Laravel\Horizon\Events\JobFailed;
+use Monolog\Handler\IFTTTHandler;
 use PhpOffice\PhpSpreadsheet\Calculation\Web\Service;
 
 class TestController extends Controller
@@ -92,6 +103,7 @@ class TestController extends Controller
     {
         return call_user_func([$this, $method], $request);
     }
+
     private function valFormat($val):?string
     {
         if ($val!==null){
@@ -101,6 +113,7 @@ class TestController extends Controller
         }else $val = "null";
         return $val;
     }
+
     public function test1($task,$amount){
         DB::connection("oracle")->beginTransaction();
         try {
@@ -125,13 +138,22 @@ class TestController extends Controller
     INSERT INTO TSK_TASKLISTS({$columns}) VALUES({$values})
 sql;
             dd($sql);
-        }catch (\Exception $e){
+        } 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"]);
@@ -149,31 +171,31 @@ sql;
         app("CacheShelfService")->_stationCacheLightOff("HAIB1-01-01");//灭灯
         app("CacheShelfService")->_stationCacheLightOff("HAIB1-02-01");//灭灯
         dd(1);*/
-        Station::query()->where("station_type_id",5)->update(["status"=>1]);
+        Station::query()->where("station_type_id", 5)->update(["status" => 1]);
         Cache::forget("CACHE_SHELF_AVAILABLE");
-        $station = ["HAIB1-01-01","HAIB1-02-01"];
-        $material = ["IDE0001824","IDE0001740","IDE0002710"];
-        Station::query()->whereIn("code",$station)->update(["status"=>0]);
-        $stations = Station::query()->whereIn("code",$station)->get();
-        $materials = MaterialBox::query()->whereIn("code",$material)->get();
+        $station = ["HAIB1-01-01", "HAIB1-02-01"];
+        $material = ["IDE0001824", "IDE0001740", "IDE0002710"];
+        Station::query()->whereIn("code", $station)->update(["status" => 0]);
+        $stations = Station::query()->whereIn("code", $station)->get();
+        $materials = MaterialBox::query()->whereIn("code", $material)->get();
         $dateTime = date("Y-m-d H:i:s");
         $task1 = StationTaskMaterialBox::query()->create([
-            'station_id'=>$stations[0]->id,
-            'material_box_id'=>$materials[0]->id,
-            'station_task_batch_id'=>1,
-            'status'=>'待处理'
+            'station_id' => $stations[0]->id,
+            'material_box_id' => $materials[0]->id,
+            'station_task_batch_id' => 1,
+            'status' => '待处理'
         ]);
-        $task2=StationTaskMaterialBox::query()->create([
-            'station_id'=>$stations[1]->id,
-            'material_box_id'=>$materials[1]->id,
-            'station_task_batch_id'=>1,
-            'status'=>'待处理'
+        $task2 = StationTaskMaterialBox::query()->create([
+            'station_id' => $stations[1]->id,
+            'material_box_id' => $materials[1]->id,
+            'station_task_batch_id' => 1,
+            'status' => '待处理'
         ]);
-        $task3=StationTaskMaterialBox::query()->create([
-            'station_id'=>6,
-            'material_box_id'=>$materials[2]->id,
-            'station_task_batch_id'=>1,
-            'status'=>'待处理'
+        $task3 = StationTaskMaterialBox::query()->create([
+            'station_id' => 6,
+            'material_box_id' => $materials[2]->id,
+            'station_task_batch_id' => 1,
+            'status' => '待处理'
         ]);
         TaskTransaction::query()->insert([[
             "doc_code" => "test",
@@ -186,10 +208,10 @@ sql;
             "type" => "出库",
             "status" => 0,
             "mark" => 2,
-            "bin_number"=>1,
-            "created_at"=>$dateTime,
-            "updated_at"=>$dateTime,
-        ],[
+            "bin_number" => 1,
+            "created_at" => $dateTime,
+            "updated_at" => $dateTime,
+        ], [
             "doc_code" => "test",
             "bar_code" => "test",
             "to_station_id" => $stations[1]->id,
@@ -200,10 +222,10 @@ sql;
             "type" => "出库",
             "status" => 0,
             "mark" => 2,
-            "bin_number"=>1,
-            "created_at"=>$dateTime,
-            "updated_at"=>$dateTime,
-        ],[
+            "bin_number" => 1,
+            "created_at" => $dateTime,
+            "updated_at" => $dateTime,
+        ], [
             "doc_code" => "test",
             "bar_code" => "test",
             "to_station_id" => 6,
@@ -214,18 +236,18 @@ sql;
             "type" => "出库",
             "status" => 3,
             "mark" => 2,
-            "bin_number"=>1,
-            "created_at"=>$dateTime,
-            "updated_at"=>$dateTime,
+            "bin_number" => 1,
+            "created_at" => $dateTime,
+            "updated_at" => $dateTime,
         ]]);
         $foreignHaiRoboticsService = new ForeignHaiRoboticsService();
         $toLocation = collect($station);
-        $taskMaterialBoxes = collect([$task1,$task2]);
+        $taskMaterialBoxes = collect([$task1, $task2]);
         $foreignHaiRoboticsService->
-        fetchGroup_multiLocation($toLocation, $taskMaterialBoxes, '', '立架出至缓存架',20,false);
-        foreach ($toLocation as $index=>$value){
-            app("CacheShelfService")->lightUp($value,'3','0',["title"=>"机器人取箱中,禁止操作"]);
-            Cache::forever("CACHE_SHELF_OCCUPANCY_{$stations[$index]->id}",true);
+        fetchGroup_multiLocation($toLocation, $taskMaterialBoxes, '', '立架出至缓存架', 20, false);
+        foreach ($toLocation as $index => $value) {
+            app("CacheShelfService")->lightUp($value, '3', '0', ["title" => "机器人取箱中,禁止操作"]);
+            Cache::forever("CACHE_SHELF_OCCUPANCY_{$stations[$index]->id}", true);
         }
         app("StationService")->locationOccupyMulti($toLocation->toArray());
     }
@@ -238,8 +260,8 @@ sql;
             ->where('class', 'like', 'https://was.baoshi56.com/package/logistic/batchUpdate%')->pluck('description');
         foreach ($descriptions as $description) {
             $description = substr($description, 9);
-            $description = \Illuminate\Support\Str::before($description,"}");
-            $obj= json_decode($description.'}',true);
+            $description = \Illuminate\Support\Str::before($description, "}");
+            $obj = json_decode($description . '}', true);
             OrderPackage::query()
                 ->whereIn('logistic_number', $obj['logistic_numbers'])
                 ->update([
@@ -249,23 +271,133 @@ sql;
         }
     }
 
-    public function updateWorkOrder(){
-        $items = WorkOrder::query()->with('order.owner')->get();
-        $params = [];
-        $items->each(function($item)use(&$params){
-            if ($item->order){
-                $owner_id = $item->order->owner_id;
-
-                $params[] = [
-                    'id' => $item->id,
-                    'order_id' => $item->order->id,
-                    'owner_id' => $owner_id,
-                ];
-                $item->owner_id = $owner_id;
-                $item->save();
+    public function testUpdateInv()
+    {
+        ini_set('max_execution_time', 0);
+        ini_set('memory_limit', '4096M');
+        $sql = <<<sql
+select FMLOTNUM,FMLOCATION,PLANTOLOCATION,CREATE_TRANSACTIONID,SKU,CUSTOMERID from TSK_TASKLISTS
+where CUSTOMERID=?
+  AND FMLOCATION= ?
+  AND OPENWHO = ?
+  AND TASKPROCESS = ?
+  AND DOCTYPE = ?
+  AND TASKTYPE = ?
+  AND LOTATT05=?
+  AND LOTATT08=?
+  AND PLANTOID = ?
+  and OPENTIME>=TO_DATE(?,'yyyy-mm-dd hh24:mi:ss')
+  and OPENTIME<=TO_DATE(?,'yyyy-mm-dd hh24:mi:ss')
+sql;
+        $CUSTOMERID = 'JIANSHANG';
+        $FMLOCATION = 'STAGEWH02';
+        $OPENWHO = 'WCS';
+        $TASKPROCESS = '00';
+        $DOCTYPE = 'ASN';
+        $TASKTYPE = 'PA';
+        $LOTATT05 = 'MJ-CP';
+        $LOTATT08 = 'ZP';
+        $PLANTOID = '*';
+        $traceid = 'JIANSHANG03';
+        $start = '2021-09-02 23:59:59';
+        $end = '2021-09-03 11:10:00';
+        $res = DB::connection("oracle")->select(DB::raw($sql),
+            [$CUSTOMERID, $FMLOCATION, $OPENWHO, $TASKPROCESS, $DOCTYPE, $TASKTYPE, $LOTATT05, $LOTATT08, $PLANTOID, $start, $end]);
+        $resItems = array_chunk($res, 200);
+        foreach ($resItems as $res) {
+            DB::connection("oracle")->beginTransaction();
+            try {
+                foreach ($res as $re) {
+                    DB::connection("oracle")->table('INV_LOT_LOC_ID')
+                        ->where([
+                            'LOTNUM' => $re->fmlotnum,
+                            'LOCATIONID' => $re->fmlocation,
+                            'CUSTOMERID' => $re->customerid,
+                            'sku' => $re->sku,
+                            'TRACEID' => '*',
+                        ])
+                        ->update([
+                            'TRACEID' => $traceid,
+                            'EDITWHO' => 'WCS_',
+                        ]);
+                    if ($re->fmlocation != $re->plantolocation) {
+                        DB::connection("oracle")->table('INV_LOT_LOC_ID')
+                            ->where([
+                                'LOTNUM' => $re->fmlotnum,
+                                'LOCATIONID' => $re->plantolocation,
+                                'CUSTOMERID' => $re->customerid,
+                                'sku' => $re->sku,
+                                'TRACEID' => '*',
+                            ])
+                            ->update([
+                                'TRACEID' => $traceid,
+                                'EDITWHO' => 'WCS_',
+                            ]);
+                    }
+                    DB::connection("oracle")->commit();
+                }
+                dd(true);
+            } catch (\Exception $e) {
+                DB::connection("oracle")->rollBack();
+                dd($e->getMessage());
             }
-        });
+        }
     }
 
+    /**
+     * 重置15天内的数据
+     */
+    public function order_packages_init()
+    {
+        OrderPackage::query()
+            ->whereBetween('created_at', [now()->subDays(15), now()])
+            ->update([
+                'is_delay_deliver' => 0,
+                'sync_routes_flag' => 0,
+                'status' => 1,
+                'exception_status' => 0,
+            ]);
+        OrderPackage::query()
+            ->whereBetween('created_at', [now()->subDays(15), now()])
+            ->whereNotNull('received_at')
+            ->update([
+                'status' => 7,
+            ]);
+    }
 
+    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')
+            ->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->update([
+                    'uploaded_to_wms'=> true,
+                    'weight'=>$orderPackingSummary->grossweight,
+                    'length'=>$orderPackingSummary->length,
+                    'width'=>$orderPackingSummary->width,
+                    'height'=>$orderPackingSummary->height,
+                    'weighed_at'=>$orderPackingSummary->edittime
+                ]);
+                dispatch(new WeightUpdateInstantBill($orderPackage));
+            }
+        }
+        return ['success' => true];
+    }
+
+    public function collectUpload()
+    {
+        /** @var OrderPackageService $service */
+        $service = app('OrderPackageService');
+       return $service->collectUpload([
+            '75803656098638',
+            '75803656098612'
+        ]);
+    }
 }

+ 38 - 32
app/Http/Controllers/WaybillController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 
 use App\CarType;
 use App\Components\AsyncResponse;
+use App\Http\Requests\GateRequest;
 use App\Owner;
 use App\Region;
 use App\Services\CarTypeService;
@@ -15,7 +16,6 @@ use App\Services\UnitService;
 use App\Services\WaybillPayoffService;
 use App\Services\WaybillPriceModelService;
 use App\Services\WaybillService;
-use App\Traits\ModelLogChanging;
 use App\TerminalPrinter;
 use App\UploadFile;
 use App\WaybillAuditLog;
@@ -36,6 +36,8 @@ use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\ValidationException;
+use Illuminate\View\View;
 use Intervention\Image\Facades\Image;
 use Oursdreams\Export\Export;
 use Ramsey\Uuid\Uuid;
@@ -50,18 +52,18 @@ class WaybillController extends Controller
     }
 
     /**
-     * @param Request $request
+     * @param GateRequest $request
      * @param OwnerService $ownerService
      * @param LogisticService $logisticService
-     * @return \Illuminate\View\View
+     * @return View
      */
-    public function index(Request $request,OwnerService $ownerService,LogisticService $logisticService)
+    public function index(GateRequest $request,OwnerService $ownerService,LogisticService $logisticService): View
     {
         $paginateParams = $request->input();
         $waybills=app('waybillService')->paginate($request->input());
-        $mac_addr = getMacAddr();
+        $macAddress = getMacAddr();
         $print = TerminalPrinter::with(['terminal','logistics'])
-            ->whereHas('terminal',function ($query)use($mac_addr){$query->where('ip',$mac_addr);})
+            ->whereHas('terminal',function ($query)use($macAddress){$query->where('ip',$macAddress);})
             ->whereHas('logistics',function ($query){$query->where('logistic_id',15);})
             ->first();
         $print = $print->printer_name??'EK100B';
@@ -71,13 +73,13 @@ class WaybillController extends Controller
             'owners' => $ownerService->getIntersectPermitting(),
             "carTypes" => CarType::query()->get(),
             'paginateParams'=>$paginateParams,
-            'uriType'=>$request->uriType??'','print_name'=> $print]);
+            'uriType'=>$request->uriType??'',
+            'print_name'=> $print]);
     }
 
 
-    public function create(Request $request,OwnerService $ownerService)
+    public function create(GateRequest $request,OwnerService $ownerService)
     {
-        if(!Gate::allows('运输管理-运单-录入')){ return redirect(url('denied'));  }
         $type=$request->type ?? "";
         if ($type==='ZF')$type='直发车';
         if ($type==='ZX')$type='专线';
@@ -85,6 +87,9 @@ class WaybillController extends Controller
         return view('transport.waybill.create',['owners'=>$ownerService->getIntersectPermitting(),'type'=>$type]);
     }
 
+    /**
+     * @throws ValidationException
+     */
     public function store(Request $request)
     {
         if(!Gate::allows('运输管理-运单-录入')){ return redirect(url('denied'));  }
@@ -96,17 +101,13 @@ class WaybillController extends Controller
 
     public function edit($id,LogisticService $logisticService,CarTypeService $carTypeService,UnitService $unitService)
     {
+        /** @var Waybill|\stdClass $waybill */
         $waybill = app('waybillService')->find($id);
         if ($waybill->order_id){
-            /** @var Waybill $waybill */
             $waybill->load("order.owner");
             $waybill->destination_city_id = app("RegionService")->getCity($waybill->order->city ?? '',$waybill->order->province ?? '');
-        }else{
-            /** @var Waybill $waybill */
-            $waybill->load("owner");
-        }
+        }else $waybill->load("owner");
         if ($waybill->merge_owner)$waybill->merge_owner = implode(",",array_column(Owner::query()->select("name")->whereIn("id",explode(",",$waybill->merge_owner))->get()->toArray(),"name"));
-        /** @var \stdClass $waybill */
         if (!$waybill)return view("exception.default",["code"=>"500","message"=>"数据已被删除或丢失"]);
         if ($waybill->deliver_at){
             $waybill->deliver_at_date=Carbon::parse($waybill->deliver_at)->format('Y-m-d');
@@ -300,7 +301,8 @@ class WaybillController extends Controller
      *          计数二存在,一不存在:
      *              城市价格区间不为空,城市价格区间都为空,城市为空,价格区间为空
      * */
-    public function isWaybillPriceModel(Request $request){
+    public function isWaybillPriceModel(Request $request): array
+    {
         $logistic_id=$request->input('logistic_id');
         $destination_city_id=$request->input('destination_city_id');
         $carrier_weight=$request->input('carrier_weight');
@@ -401,17 +403,16 @@ class WaybillController extends Controller
         $data=$request->input();
         $waybill=app('waybillService')->find($id);
         $waybill->fill($data);
-        if ($waybill->save()){
-            app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($waybill),Auth::user()['id']);
-            return redirect('transport/waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”修改成功');
-        }
+        $waybill->save();
+        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($waybill),Auth::user()['id']);
+        return redirect('transport/waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”修改成功');
     }
 
     public function waybillAudit(Request $request){
         if(!Gate::allows('运输管理-运单-运单审核')){ return redirect(url('/'));  }
         $id=$request->input('id');
         $waybill=app('waybillService')->find($id);
-        $isAudit=WaybillAuditLog::whereRaw('waybill_id = ? and audit_stage = ?',[$id,"运单阶段"])->first();
+        $isAudit=WaybillAuditLog::query()->whereRaw('waybill_id = ? and audit_stage = ?',[$id,"运单阶段"])->first();
         if (empty($isAudit)){
             $waybillAuditLog=new WaybillAuditLog([
                 'waybill_id'=>$id,
@@ -778,7 +779,7 @@ SQL;
 
     private function deliveringQuery(Request $request): Builder
     {
-        $waybills= Waybill::query()->where("type","专线")->with(["order","logistic"])
+        $waybills= Waybill::query()->where("type","专线")->with(["order","logistic","amountUnit"])
         ->whereNotNull("logistic_id")->whereNotNull("deliver_at")->whereIn("status",["已审核","待终审"]);
         if (!Auth::user()->isSuperAdmin()){
             $carriersUsers=DB::table('logistic_user')->where('user_id',Auth::id())->get();
@@ -819,8 +820,9 @@ SQL;
         $errors=Validator::make($request->input(),[
             'id'=>'required|integer',
             'carrier_bill'=>'required',
-            'inquire_tel'=>'nullable',
-            'amount'=>'nullable|integer',
+            'inquire_tel'=>'required',
+            'amount'=>'required|integer',
+            'amount_unit_name'=>'required|string',
             'carrier_weight'=>'required_without:carrier_weight_other|nullable|numeric',
             'carrier_weight_other'=>'required_without:carrier_weight|nullable|numeric',
         ],[
@@ -831,14 +833,16 @@ SQL;
         ],[
             'carrier_bill'=>'运单号',
             'inquire_tel'=>'查件电话',
+            'amount_unit_name'=>'数量单位',
             'amount'=>'件数',
             'carrier_weight'=>'体积',
             'carrier_weight_other'=>'重量',
         ])->errors();
+        if ($request->input("amount_unit_name")!='件' && $request->input("amount_unit_name")!='托')$errors->add("amount_unit_name","非法参数");
+        if (count($errors)>0)return ["errors"=>$errors];
         $unit = app("UnitService")->getUnit("kg");
-        $unit1 = app("UnitService")->getUnit("件");
+        $unit1 = app("UnitService")->getUnit($request->input("amount_unit_name"));
         $unit2 = app("UnitService")->getUnit("m³");
-        if (count($errors)>0)return ["errors"=>$errors];
         $waybill=Waybill::query()->find($request->input('id'));
         if (!$waybill)return ["error"=>"未找到该运单!"];
         $request->offsetSet("carrier_weight_unit_id",$unit2->id);
@@ -1125,15 +1129,17 @@ SQL;
         $destroys = [];
         $owner = [$waybill->owner_id];
         if (array_search($waybill->status,["未审核","已审核","待终审"])===false)$this->error("运单禁止合并");
+
+        $remark = [];
+        if ($waybill->ordering_remark)$remark[] = $waybill->ordering_remark;
         for ($i=1;$i<$waybills->count();$i++){
             //信息一致性校验
             $identical = ($waybill->order && ($waybills[$i]->order->consignee_name!=$waybill->order->consignee_name
-                        || $waybills[$i]->order->consignee_phone!=$waybill->order->consignee_phone
-                        || $waybills[$i]->order->address!=$waybill->order->address)) ||
+                        || $waybills[$i]->order->consignee_phone!=$waybill->order->consignee_phone)) ||
                 (!$waybill->order && ($waybills[$i]->recipient!=$waybill->recipient
                     || $waybills[$i]->recipient_mobile!=$waybill->recipient_mobile
                     || $waybills[$i]->destination!=$waybill->destination));
-            if (array_search($waybills[$i]->status,["未审核","已审核"])===false
+            if (array_search($waybills[$i]->status,["未审核","已审核","待终审"])===false
                 || $identical)$this->error("信息不一致,无法进行合并");
             $destroys[] = $waybills[$i]->id;
             $waybill->source_bill .= $waybills[$i]->source_bill ? ",".$waybills[$i]->source_bill : '';
@@ -1143,9 +1149,10 @@ SQL;
             $waybill->other_fee += (double)$waybills[$i]->other_fee;
             $waybill->warehouse_weight_other += (double)$waybills[$i]->warehouse_weight_other;
             $waybill->warehouse_weight += (double)$waybills[$i]->warehouse_weight;
-            $waybill->ordering_remark = $waybill->ordering_remark ? $waybill->ordering_remark.",".$waybills[$i]->ordering_remark : $waybills[$i]->ordering_remark;
+            if ($waybills[$i]->ordering_remark)$remark[] = $waybills[$i]->ordering_remark;
             $owner[] = $waybills[$i]->owner_id;
         }
+        $waybill->ordering_remark = implode(",",array_unique($remark));
         if (strlen($waybill->source_bill)>191 || strlen($waybill->wms_bill_number)>191)$this->error("单号超长,无法合并");
         $owner = array_unique($owner);
         if (count($owner)>1)$waybill->merge_owner = implode(',',$owner);
@@ -1291,8 +1298,7 @@ SQL;
             foreach ($waybills as $item){
                 //信息一致性校验
                 $identical = ($waybill->order && ($item->order->consignee_name!=$waybill->order->consignee_name
-                            || $item->order->consignee_phone!=$waybill->order->consignee_phone
-                            || $item->order->address!=$waybill->order->address)) ||
+                            || $item->order->consignee_phone!=$waybill->order->consignee_phone)) ||
                     (!$waybill->order && ($item->recipient!=$waybill->recipient
                             || $item->recipient_mobile!=$waybill->recipient_mobile));
                 if ($identical)$this->error("订单信息不一致,无法统一发货");

+ 9 - 0
app/Http/Controllers/WorkOrderController.php

@@ -100,4 +100,13 @@ class WorkOrderController extends Controller
         return ['success' => true,'data' => $items];
     }
 
+    // 删除
+    public function destroyApi($id): array
+    {
+        if (Gate::denies('订单管理-工单处理-删除'))
+            return ['success' => false,'message' => '没有对应权限'];
+        WorkOrder::query()->where('id',$id)->Delete();
+        return ['success' => true];
+    }
+
 }

+ 3 - 9
app/Http/Controllers/api/thirdPart/haiq/StorageController.php

@@ -354,14 +354,8 @@ class StorageController
     public function paddingEmptyBox()
     {
         $amount = \request("amount") ?: 1;
-        $blacklist = [];
-        $boxes = "";
-        for ($i=0;$i<$amount;$i++){
-            $box = app("MaterialBoxService")->getAnEmptyBoxSortedByOwner(null,$blacklist);
-            if (!$box)break;
-            $boxes .= $box->code.",";
-            $blacklist[] = $box->id;
-        }
-        $this->success(rtrim($boxes,","));
+        $boxes = app("MaterialBoxService")->getAnEmptyBoxSortedByOwner(null,[],$amount);
+        if (!is_array($boxes))$boxes = [$boxes];
+        $this->success(implode(",",array_column($boxes,"code")));
     }
 }

+ 5 - 5
app/Http/Requests/GateRequest.php

@@ -122,12 +122,12 @@ class GateRequest extends FormRequest
      */
     public function sameOriginMatching()
     {
+        $url = null;
         //目标节点存在
-        if ($this->tracks){
-            $url = $this->searchOrigin(app("MenuService")->getVisibleFunctionList());
-            header('Location: /'.$url);
-            die();
-        }
+        if ($this->tracks)$url = $this->searchOrigin(app("MenuService")->getVisibleFunctionList());
+        if (!$url)$url = 'denied';
+        header('Location: /'.$url,true,301);
+        die();
         //目标节点为空的话说明一级节点都无权访问
         // 此时返回一级同源节点就无意义 会产生误导性,所以前往无权页面
         //正常情况下这个预设不会被正常用户触发

+ 1 - 0
app/Jobs/LogisticYTOSync.php

@@ -27,6 +27,7 @@ class LogisticYTOSync implements ShouldQueue
 
     protected $logistic_number;
     protected $logisticYTOService;
+    /** @var orderPackageReceivedSyncService OrderPackageReceivedSyncService */
     protected $orderPackageReceivedSyncService;
 
     /**

+ 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]);
     }
 }

+ 1 - 1
app/OracleDOCASNHeader.php

@@ -29,6 +29,6 @@ class OracleDOCASNHeader extends Model
     public function asnDetails()
     {
         return $this->hasMany(OracleDOCASNDetail::class,'asnno','asnno')
-            ->select('asnno','asnlineno','customerid','sku','skudescrc','linestatus','lotatt08','lotatt05','receivedqty','expectedqty','addtime','edittime');
+            ->select('asnno','asnlineno','customerid','sku','skudescrc','linestatus','lotatt08','lotatt05','receivedqty','receivedqty_each','expectedqty','addtime','edittime');
     }
 }

+ 3 - 2
app/OracleIdxAsrsReceive.php

@@ -38,10 +38,11 @@ class OracleIdxAsrsReceive extends Model
             $inserts='';
             $values=[];
             foreach($logisticNumbers_toInsert as $logisticNumber){
+                if (!$logisticNumber)continue;
                 $inserts .= " into idx_asrs_receive (grouptaskid,grouptasksequence,userdefine1,userdefine2,addwho,addtime)values(?,?,?,?,?,?) ";
-                $values[] = $logisticNumber??'';
+                $values[] = $logisticNumber;
                 $values[] = 1;
-                $values[] = $logisticNumber??'';
+                $values[] = $logisticNumber;
                 $values[] = $weight;
                 $values[] = 'WAS';
                 $values[] = Carbon::now();

+ 10 - 1
app/OrderIssue.php

@@ -36,7 +36,9 @@ class OrderIssue extends Model
         'logistic_indemnity_money', 'logistic_express_remission',
         'baoshi_indemnity_money', 'baoshi_express_remission', 'user_workgroup_id',
         'custom_code','imported_status','finance_confirm',
-        'hidden_tag','archive_at'];
+        'hidden_tag','archive_at',
+        'is_intercept'
+    ];
     /*
      * second_client_no 二次客户订单号
      * second_logistic_number 二次运单号 【二次运单号可以单独存在,当二次客户订单号有对应的订单信息时,显示的是二次客户订单号对应的运单号,没有的话显示二次原单号】
@@ -50,6 +52,7 @@ class OrderIssue extends Model
      * finance_confirm 财务确认
      * hidden_tag 隐藏标识
      * archive_at 归档时间
+     * is_intercept 是否拦截
      */
     protected $appends = [];
 
@@ -312,4 +315,10 @@ class OrderIssue extends Model
     {
         return $this->belongsToMany(UserWorkgroup::class);
     }
+
+    // 库内拦截
+    public function intercept(): bool
+    {
+        return $this->update(['is_intercept' => 1]);
+    }
 }

+ 55 - 26
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;
@@ -45,61 +41,94 @@ class OrderPackage extends Model
         'uploaded_to_wms',
         'sync_routes_flag',
         'is_manual_update',
+        'exception_status',
+        'is_delay_deliver',
     ];
 
     protected $casts = [
         'transfer_status' => 'array',
         'sync_routes_flag' => 'boolean',
         'is_manual_update' => 'boolean',
+        'is_delay_deliver' => 'boolean',
+    ];
+
+    protected $dates = [
+        'sent_at',
+        'received_at',
+        'weighed_at',
     ];
 
     static public $enums = [
         'status' => [
-            ''=>0,
-            '无'=>1,
-            '已称重'=>2,
-            '已揽收'=>3,
-            '揽件异常'=>4,
-            '疑似库内丢件'=>5,
-            '在途'=>6,
-            '在途异常'=>7,
-            '派送中'=>8,
-            '派送异常'=>9,
-            '返回中'=>10,
-            '返回异常'=>11,
-            '返回派件'=>12,
-            '其他异常'=>13,
-            '已签收'=>14,
-            '其他'=>14,
+            '' => 0,
+            '生成订单' => 1,
+            '已复核' => 2,
+            '已称重' => 3,
+            '已揽件' => 4,
+            '在途' => 5,
+            '派送中' => 6,
+            '已签收' => 7,
+            '其他' => 8,
+            '返回中' => 9,
+        ],
+        'exception_status' => [
+            '' => 0,
+            '单号异常' => 1,
+            '无法获取路由' => 2,
+            '延迟发货' => 3,
+            '疑似库内丢件' => 4,
+            '在途异常' => 5,
+            '揽件异常' => 6,
+            '派送异常' => 7,
         ],
     ];
 
     function __construct(array $attributes = [])
     {
         foreach (self::$enums as &$enum) {
-            $enum=$enum+array_flip($enum);
+            $enum = $enum + array_flip($enum);
         }
         parent::__construct($attributes);
     }
 
     public function getStatusAttribute($value)
     {
-        if(!$value || !isset(self::$enums['status'][$value]))return '';
+        if (!$value || !isset(self::$enums['status'][$value])) return '';
         return self::$enums['status'][$value];
     }
+
     public function setStatusAttribute($value)
     {
-        if(!$value)return 0;
-        if (!(self::$enums['status'][$value] ?? false))return 0;
-        $this->attributes['status']=self::$enums['status'][$value];
+        if (!$value) return 0;
+        if (!(self::$enums['status'][$value] ?? false)) return 0;
+        $this->attributes['status'] = self::$enums['status'][$value];
     }
 
     public static function switchStatus($value): int
     {
-        if (!(self::$enums['status'][$value] ?? false))return 0;
+        if (!(self::$enums['status'][$value] ?? false)) return 0;
         return self::$enums['status'][$value];
     }
 
+    public function getExceptionStatusAttribute($value)
+    {
+        if (!$value || !isset(self::$enums['exception_status'][$value])) return '';
+        return self::$enums['exception_status'][$value];
+    }
+
+    public function setExceptionStatusAttribute($value)
+    {
+        if (!$value) return 0;
+        if (!(self::$enums['exception_status'][$value] ?? false)) return 0;
+        $this->attributes['exception_status'] = self::$enums['exception_status'][$value];
+    }
+
+    public static function switchExceptionStatus($value): int
+    {
+        if (!(self::$enums['exception_status'][$value] ?? false)) return 0;
+        return self::$enums['exception_status'][$value];
+    }
+
     public function order()
     {
         return $this->belongsTo('App\Order', 'order_id', 'id');

+ 16 - 7
app/Services/HandInStorageService.php

@@ -616,21 +616,31 @@ sql;
             if ($asnDetail['asnno'] == $info['asnno'] &&
                 $asnDetail['asnlineno'] == $info['asnlineno'] &&
                 $asnDetail['customerid'] == $info['customerid'] &&
-                $asnDetail['sku'] == $info['sku']) $receiveAsn = $asnDetail;
+                $asnDetail['sku'] == $info['sku'] ){
+                $receiveAsn = $asnDetail;
+            }
         }
-//        return $db->transaction(function () use ($db, $info, $receiveAsn, $invlotatt, $time, $who, $asn) {
-        if ($receiveAsn && (int)$receiveAsn['receivedqty'] + (int)$info['amount'] < (int)$receiveAsn['expectedqty']) {
-            //asn_detail 收货数量+已收数量<预期数量
+
+        if (!$receiveAsn) return false;
+
+        $receivedQty = (int)($receiveAsn['receivedqty']??$receiveAsn['receivedqty_each']);  // 已收货数量
+        $amount = (int) $info['amount'];                    // 当前收货数量
+        $expectedQty = (int)$receiveAsn['expectedqty'];     // 预期数量
+
+        if ($receivedQty + $amount < $expectedQty) {
+            // 已收货数量+当前收货数量 < 预期数量
             $db->update(DB::raw("UPDATE DOC_ASN_DETAILS SET receivedqty = receivedqty + ?,receivedqty_each = receivedqty_each + ?,linestatus = '30',holdrejectcode ='OK',
                 reserve_flag ='Y',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),receivedtime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ?,
              lotatt01 =?,lotatt02 =?,lotatt03 =?,lotatt04 =?,lotatt05 =?,lotatt06 =?,lotatt07 =?,lotatt08=? WHERE asnno = ? and asnlineno = ?"),
                 [(int)$info['amount'], (int)$info['amount'], $time, $time, $who, $invlotatt['lotatt01'], $invlotatt['lotatt02'], $invlotatt['lotatt03'], $invlotatt['lotatt04'],
                     $invlotatt['lotatt05'], $invlotatt['lotatt06'], $invlotatt['lotatt07'], $invlotatt['lotatt08'], $info['asnno'], $info['asnlineno']]);
+
             //asn_header 部分收货状态
             $db->update(DB::raw("UPDATE DOC_ASN_HEADER SET asnstatus = '30',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ?"),
                 [$time, $who, $info['asnno']]);
-        } elseif ($receiveAsn && (int)$receiveAsn['receivedqty'] + (int)$info['amount'] == (int)$receiveAsn['expectedqty']) {
-            //asn_detail 收货数量+已收数量=预期数量
+
+        } elseif ($receivedQty + $amount == $expectedQty) {
+            // 已收货数量+当前收货数量 = 预期数量
             $db->update(DB::raw("UPDATE DOC_ASN_DETAILS SET receivedqty=receivedqty+?,receivedqty_each=receivedqty_each+?,linestatus = '40',
                 edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),receivedtime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ?,holdrejectcode='OK',
                 reserve_flag='Y',lotatt01=?,lotatt02=?,lotatt03=?,lotatt04=?,lotatt05=?,lotatt06=?,lotatt07=?,lotatt08=? WHERE asnno = ? and asnlineno = ?"),
@@ -647,7 +657,6 @@ sql;
             }
         }
         return true;
-//        });
     }
 
     /**

+ 0 - 3
app/Services/LogisticAliJiSuApiService.php

@@ -61,9 +61,6 @@ class LogisticAliJiSuApiService
                 if ($result['status'] == '已签收') $result['received_at'] = $lastNativeRoute->time;
                 $result['transfer_status'] = $this->getTransferStatus($list);
                 $result['routes_length'] = array_key_exists('transfer_status', $result) ? count($result['transfer_status']) : 0;
-                $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
-                $exceptionData = $orderPackageReceivedSyncService->setExceptionType($result, $lastNativeRoute ? $lastNativeRoute->time : null);
-
             } else {
                 $result['status'] = null;
                 $result['transfer_status'] = [];

+ 6 - 13
app/Services/LogisticSFService.php

@@ -5,10 +5,9 @@ namespace App\Services;
 
 
 use App\Exceptions\WarningException;
-use App\OrderPackage;
+use App\Traits\LogisticSyncTrait;
 use Exception;
 use Illuminate\Http\Client\Response;
-use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Http;
 
 class LogisticSFService
@@ -125,9 +124,9 @@ xml;
         }
         foreach ($routs as $route) {
             $route = get_object_vars($route)['@attributes'];
-            $data['accept_time'] = $route['accept_time']??'';
-            $data['accept_address'] = $route['accept_address']??'';
-            $data['remark'] = $route['remark']??'';
+            $data['accept_time'] = $route['accept_time'] ?? '';
+            $data['accept_address'] = $route['accept_address'] ?? '';
+            $data['remark'] = $route['remark'] ?? '';
             $result[] = $data;
         }
         return $result;
@@ -153,26 +152,20 @@ xml;
                 case 106://航空板箱到达
                     $data['status'] = '在途';
                     break;
-                case 33:
-                    $data['status'] = '派送异常';
-                    break;
                 case 204:
                 case 44:
                     $data['status'] = '派送中';
                     break;
                 case 50:
-                    $data['status'] = '已揽';
+                    $data['status'] = '已揽';
                     break;
                 case 607:
                 case 8000:
+                case 125:
                 case 80:
                     $data['status'] = '已签收';
                     $data['received_at'] = $lastRoute[$this->protected_switch['received_at']];
                     break;
-                case 648:
-                case 99:
-                    $data['status'] = '返回中';
-                    break;
                 case 70:
                     $data['status'] = '其他';
                     break;

+ 3 - 1
app/Services/LogisticYDService.php

@@ -3,6 +3,7 @@
 namespace App\Services;
 
 use App\OrderPackage;
+use App\Traits\LogisticSyncTrait;
 use App\Traits\ServiceAppAop;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\Http;
@@ -119,6 +120,7 @@ class LogisticYDService
                 }
                 $result['transfer_status'] = $this->getTransferStatus($nativeRoutes);
                 $result['routes_length'] = array_key_exists('transfer_status', $result) ? count($result['transfer_status']) : 0;
+
             } else {
                 $result['status'] = null;
                 $result['transfer_status'] = [];
@@ -140,7 +142,7 @@ class LogisticYDService
         $status = null;
         switch ($nativeData->status) {
             case 'GOT':
-                $status = '已揽';
+                $status = '已揽';
                 break;
             case 'TRANSIT':
                 $status = '在途';

+ 1 - 3
app/Services/LogisticYTOService.php

@@ -64,8 +64,6 @@ class LogisticYTOService
                 if ($result['status'] == '已签收') $result['received_at'] = $lastNativeRoute->upload_Time;
                 $result['transfer_status'] = $this->getTransferStatus($response);
                 $result['routes_length'] = array_key_exists('transfer_status', $result) ? count($result['transfer_status']) : 0;
-                $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
-                $exceptionData = $orderPackageReceivedSyncService->setExceptionType($result, $lastNativeRoute ? $lastNativeRoute->upload_Time : null);
             } else {
                 $result['status'] = null;
                 $result['transfer_status'] = [];
@@ -84,7 +82,7 @@ class LogisticYTOService
         switch ($nativeData->infoContent) {
             case 'ARRIVAL':
             case 'GOT':
-                $status = '已揽';
+                $status = '已揽';
                 break;
             case 'DEPARTURE':
             case 'PACKAGE':

+ 5 - 2
app/Services/LogisticZopService.php

@@ -4,12 +4,12 @@
 namespace App\Services;
 
 use App\OrderPackage;
+use App\Traits\LogisticSyncTrait;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\Http;
 
 class LogisticZopService implements LogisticRouteInterface
 {
-
     public function query($logistic_number)
     {
         $url = config('api_logistic.ZTO.url');
@@ -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,
@@ -60,7 +63,7 @@ class LogisticZopService implements LogisticRouteInterface
         $received_at = null;
         switch ($lastRoute->scanType) {
             case '收件':
-                $status = '已揽';
+                $status = '已揽';
                 break;
             case '到件':
             case '发件':

+ 27 - 9
app/Services/MaterialBoxService.php

@@ -23,12 +23,14 @@ class MaterialBoxService
      *
      * @param MaterialBoxModel|\stdClass $model
      * @param array $blacklist
+     * @param int $multi
      *
-     * @return MaterialBox|null
+     * @return MaterialBox|null|array
      */
-    public function getAnEmptyBox(MaterialBoxModel $model,array $blacklist = []):?MaterialBox
+    public function getAnEmptyBox(MaterialBoxModel $model,array $blacklist = [], int $multi = 1)
     {
         $id = 0;
+        $tarBoxes = [];
         while (true){
             //检测WAS
             $boxes = MaterialBox::query()->select('id',"code")
@@ -60,9 +62,14 @@ SELECT LOCATIONID FROM (SELECT LOCATIONID FROM (SELECT LOCATIONID,SUM(QTY+QTYPA)
                             LOCATIONID HAVING (COUNT(*)>={$model->maximum_kind})
 sql;
             foreach (DB::connection("oracle")->select(DB::raw($sql)) as $item)unset($ides[$item->locationid]);
-            if ($ides)return current($ides);
+            foreach ($ides as $box){
+                $tarBoxes[] = $box;
+                $multi--;
+                if (!$multi)break 2;
+            }
         }
-        return null;
+        $len = count($tarBoxes);
+        return $len==1 ? $tarBoxes[0] : ($len==0 ? null : $tarBoxes);
     }
 
     public function checkHaiQ(array $boxCodes)
@@ -85,17 +92,28 @@ sql;
      *
      * @param integer|null $ownerId
      * @param array $blacklist
+     * @param int $multi
      *
-     * @return MaterialBox|null
+     * @return MaterialBox|null|array
      */
-    public function getAnEmptyBoxSortedByOwner(?int $ownerId=null, array $blacklist=[]):?MaterialBox
+    public function getAnEmptyBoxSortedByOwner(?int $ownerId=null, array $blacklist=[], int $multi = 1)
     {
         $models = app("MaterialBoxModelService")->getModelSortedByOwner($ownerId);
+        $tarBoxes = [];
         foreach ($models as $model){
-            $box = $this->getAnEmptyBox($model,$blacklist);
-            if ($box)return $box;
+            $box = $this->getAnEmptyBox($model,$blacklist,$multi);
+            if (!$box)continue;
+            if (is_array($box)){
+                $tarBoxes = array_merge($tarBoxes,$box);
+                $multi -= count($box);
+            }else{
+                $tarBoxes[] = $box;
+                $multi--;
+            }
+            if (!$multi)break;
         }
-        return null;
+        $len = count($tarBoxes);
+        return $len==1 ? $tarBoxes[0] : ($len==0 ? null : $tarBoxes);
     }
 
     /**

+ 8 - 0
app/Services/OrderIssueService.php

@@ -440,5 +440,13 @@ class OrderIssueService
         $order_issue_type_query = OrderIssueType::query()->select('id')->where('name' ,'拦截');
         return OrderIssue::query()->whereIn('order_id',$order_package_query)->whereIn('order_issue_type_id',$order_issue_type_query)->count() ;
     }
+
+    // 已拦截 在 问题件 的显示
+    public function intercept($logistic_number)
+    {
+        $order_package = OrderPackage::query()->select('order_id')->where('logistic_number',$logistic_number)->first();
+        if (!$order_package) return;
+        OrderIssue::query()->where('order_id',$order_package->order_id)->update(['is_intercept' => 1]);
+    }
 }
 

+ 39 - 30
app/Services/OrderPackageReceivedSyncService.php

@@ -13,11 +13,13 @@ use App\OrderPackage;
 use Carbon\Carbon;
 use Exception;
 use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Str;
 
 class OrderPackageReceivedSyncService
 {
     protected $logisticSFService;
     protected $logisticZopService;
+    use \App\Traits\LogisticSyncTrait;
 
     /**
      * 同步快递信息
@@ -25,25 +27,35 @@ class OrderPackageReceivedSyncService
      * 2 如果当前时间小于等于初始化时间,执行初始化脚本,将数据库中全部小于等于初始化时间的数据更新
      * @throws Exception
      */
-    public function syncLogisticRoute($is_to_init = false)
+    public function syncLogisticRoute($is_to_init = false,$logistic_numbers = [])
     {
         ini_set('max_execution_time', 2 * 60 * 60);
         ini_set('memory_limit', '1024M');
         //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法", '');
-        $query = OrderPackage::query()
-            ->select(['logistic_number', 'order_id', 'id'])
-            ->with(['order' => function ($query) {
-                return $query->select(['id', 'logistic_id'])->with('logistic:id,name,code');
-            }]);
-        if ($is_to_init) {//当前时间小于等于初始化时间
-            $initDate = Carbon::parse(config('api_logistic.init_date'));
-            //初始化查询一个月的数据,exception为否
-            $query = $query->where('sent_at', '>=', $initDate)
-                ->whereNull('received_at');
-        } else {//查询20天以内的数据
-            $query = $query->where('sent_at', '>=', now()->subDays(config('api_logistic.querying_days'))->startOfDay())
-                ->whereNull('received_at');
+        if (empty($logistic_numbers)) {
+            $query = OrderPackage::query()
+                ->select(['logistic_number', 'order_id', 'id'])
+                ->with(['order' => function ($query) {
+                    return $query->select(['id', 'logistic_id'])->with('logistic:id,name,code');
+                }]);
+            if ($is_to_init) {//当前时间小于等于初始化时间
+                $initDate = Carbon::parse(config('api_logistic.init_date'));
+                //初始化查询一个月的数据,exception为否
+                $query = $query->where('created_at', '>=', $initDate)
+                    ->whereNull('received_at');
+            } else {//查询20天以内的数据
+                $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days'))->startOfDay())
+                    ->whereNull('received_at');
+            }
+        } else {
+            $query = OrderPackage::query()
+                ->select(['logistic_number', 'order_id', 'id'])
+                ->with(['order' => function ($query) {
+                    return $query->select(['id', 'logistic_id'])->with('logistic:id,name,code');
+                }])
+                ->whereIn('logistic_number', $logistic_numbers);
         }
+
         $query->chunkById(1000, function ($orderPackages) {
             //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法", json_encode(data_get($orderPackages,'*.logistic_number')));
             $logisticNumbers = $this->buildData($orderPackages);
@@ -95,7 +107,7 @@ class OrderPackageReceivedSyncService
                     $builder->from('logistics')->selectRaw('id')->where('type', '=', '快递')->whereNotIn('belong_company', ['顺丰', '中通', '韵达', '圆通', '京东']);
                 });
             });
-        $query = $query->where('sent_at', '>=', now()->subDays(config('api_logistic.querying_days')))
+        $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days')))
             ->whereNull('received_at');
 
         $query->chunkById(200, function ($orderPackages) {
@@ -187,24 +199,21 @@ class OrderPackageReceivedSyncService
             if ($logisticResponse['received_at'] ?? false) {
                 $logisticResponse['status'] = '已签收';
             }
-            //未查询到路由信息改为  揽件异常
-            if (empty($logisticResponse['transfer_status'])) {
-                $logisticResponse['status'] = '揽件异常';
-                //未查询到路由信息且未称重的   疑似库内丢件
-                if (empty($orderPackage->weighed_at)) {
-                    $logisticResponse['status'] = '疑似库内丢件';
-                }
-            } else if (count($logisticResponse['transfer_status'])<=3) {//快递记录不为空但是小于3条
-                $logisticResponse['status'] = '揽件异常';
-            }
             //标记为手动更新的 status不更新
             if ($orderPackage->is_manual_update) {
-                unset($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','#','-'])) {
+                $logisticResponse['exception_status'] = '单号异常';
             }
-            if (isset($logisticResponse['status'])) $orderPackage->status = $logisticResponse['status'];
-            if (isset($logisticResponse['received_at'])) $orderPackage->received_at = $logisticResponse['received_at'];
-            if (isset($logisticResponse['transfer_status']) && !empty($logisticResponse['transfer_status'])) $orderPackage->transfer_status = $logisticResponse['transfer_status'];
-            $orderPackage->save();
+            if (isset($logisticResponse['exception_status'])) $logisticResponse['exception_status'] = OrderPackage::switchExceptionStatus($logisticResponse['exception_status']);
+            if (isset($logisticResponse['status'])) $logisticResponse['status'] = OrderPackage::switchStatus($logisticResponse['status']);
+            if (isset($logisticResponse['routes_length'])) unset($logisticResponse['routes_length']);
+            OrderPackage::query()->where('logistic_number', $logisticResponse['logistic_number'])
+                ->update($logisticResponse);
         }
     }
 

+ 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' => '一键揽收上传成功'];
+    }
 }

+ 43 - 5
app/Services/OrderService.php

@@ -30,6 +30,7 @@ use App\Warehouse;
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
 use App\Traits\ServiceAppAop;
@@ -88,6 +89,7 @@ class OrderService
         $ordernos = $params["ordernos"] ?? null;
         $edisendflag2=$params["edisendflag2"] ?? null;
         $edisendflag=$params["edisendflag"] ?? null;
+        $manualflag=$params["manualflag"] ?? null;
         $checkAllSign = $params['checkAllSign'] ?? null;
         if ($ordernos){
             $sql .= " AND orderno IN ".$ordernos;
@@ -219,6 +221,7 @@ class OrderService
         }
         if ($edisendflag2) $sql.=" and edisendflag2 like '".$edisendflag2."%'";
         if ($edisendflag) $sql.=" and edisendflag like '".$edisendflag."%'";
+        if ($manualflag) $sql.=" and manualflag = '".$manualflag."'";
         if ($soreference1){
             $arr=array_values(array_filter(preg_split('/[,, ]+/is', $soreference1)));
             if (count($arr)==1){
@@ -252,9 +255,9 @@ class OrderService
             if ($ordernos)$params['ordernos'] = $ordernos;
             else return null;
         }
-        $sql="SELECT * FROM (select ACT_ALLOCATION_DETAILS.CHECKTIME,DOC_ORDER_HEADER.addtime,DOC_ORDER_HEADER.C_PROVINCE,DOC_ORDER_HEADER.C_CITY,DOC_ORDER_HEADER.C_DISTRICT,DOC_ORDER_HEADER.C_CONTACT,DOC_ORDER_HEADER.OrderNo,DOC_ORDER_HEADER.SOStatus,DOC_ORDER_HEADER.WAREHOUSEID,DOC_ORDER_HEADER.CustomerID as header_customer_id
+        $sql="SELECT * FROM (select ACT_ALLOCATION_DETAILS.CHECKTIME,DOC_ORDER_HEADER.addtime,DOC_ORDER_HEADER.C_PROVINCE,DOC_ORDER_HEADER.C_CITY,DOC_ORDER_HEADER.MANUALFLAG,DOC_ORDER_HEADER.C_DISTRICT,DOC_ORDER_HEADER.C_CONTACT,DOC_ORDER_HEADER.OrderNo,DOC_ORDER_HEADER.SOStatus,DOC_ORDER_HEADER.WAREHOUSEID,DOC_ORDER_HEADER.CustomerID as header_customer_id
         ,DOC_ORDER_HEADER.C_Tel2,DOC_ORDER_HEADER.C_Tel1,DOC_ORDER_HEADER.CarrierName,DOC_ORDER_HEADER.IssuePartyName,DOC_ORDER_HEADER.EDIREMARKS2,
-       DOC_ORDER_HEADER.WaveNo,DOC_ORDER_HEADER.SOReference1
+       DOC_ORDER_HEADER.WaveNo,DOC_ORDER_HEADER.SOReference1, DOC_ORDER_HEADER.SOREFERENCE5 as code5
         ,NVL(ACT_ALLOCATION_DETAILS.PICKTOTRACEID,DOC_ORDER_HEADER.soreference5) as soreference5,DOC_ORDER_HEADER.EDISENDFLAG2,DOC_ORDER_HEADER.EDISendTime2,DOC_ORDER_HEADER.Notes,DOC_ORDER_HEADER.ERPCANCELFLAG,
        DOC_ORDER_HEADER.Picking_Print_Flag,DOC_ORDER_HEADER.EDISENDFLAG
         ,DOC_ORDER_HEADER.ReleaseStatus,DOC_ORDER_HEADER.C_Address1,DOC_ORDER_HEADER.OrderTime,DOC_Order_Details.CustomerID,
@@ -264,7 +267,7 @@ class OrderService
         $sql=$this->preciseQuery($params,$sql);
         ;$sql.=" ) as counted from (";
         if ($paginate && $page)$sql.=" select * from (";
-        $sql.=" select ROWNUM as rn,DOC_ORDER_HEADER.addtime,DOC_ORDER_HEADER.C_PROVINCE,DOC_ORDER_HEADER.C_CITY,DOC_ORDER_HEADER.C_DISTRICT,DOC_ORDER_HEADER.C_CONTACT,DOC_ORDER_HEADER.OrderNo,DOC_ORDER_HEADER.SOStatus,DOC_ORDER_HEADER.WAREHOUSEID,DOC_ORDER_HEADER.CustomerID
+        $sql.=" select ROWNUM as rn,DOC_ORDER_HEADER.addtime,DOC_ORDER_HEADER.C_PROVINCE,DOC_ORDER_HEADER.C_CITY,DOC_ORDER_HEADER.MANUALFLAG,DOC_ORDER_HEADER.C_DISTRICT,DOC_ORDER_HEADER.C_CONTACT,DOC_ORDER_HEADER.OrderNo,DOC_ORDER_HEADER.SOStatus,DOC_ORDER_HEADER.WAREHOUSEID,DOC_ORDER_HEADER.CustomerID
                           ,DOC_ORDER_HEADER.C_Tel2,DOC_ORDER_HEADER.C_Tel1,DOC_ORDER_HEADER.CarrierName,DOC_ORDER_HEADER.IssuePartyName,
                          DOC_ORDER_HEADER.WaveNo,DOC_ORDER_HEADER.SOReference1
                           ,DOC_ORDER_HEADER.soreference5,DOC_ORDER_HEADER.EDISENDFLAG2,DOC_ORDER_HEADER.EDISendTime2,DOC_ORDER_HEADER.Notes,DOC_ORDER_HEADER.ERPCANCELFLAG,
@@ -295,9 +298,9 @@ class OrderService
                       left join  BAS_SKU on DOC_Order_Details.CustomerID=BAS_SKU.CustomerID and DOC_Order_Details.SKU=BAS_SKU.SKU
                       left join  ACT_ALLOCATION_DETAILS on DOC_Order_Details.orderno = ACT_ALLOCATION_DETAILS.orderno
                       and DOC_Order_Details.ORDERLINENO = ACT_ALLOCATION_DETAILS.ORDERLINENO
-                      GROUP BY ACT_ALLOCATION_DETAILS.CHECKTIME,DOC_ORDER_HEADER.addtime,DOC_ORDER_HEADER.C_PROVINCE,DOC_ORDER_HEADER.C_CITY,
+                      GROUP BY ACT_ALLOCATION_DETAILS.CHECKTIME,DOC_ORDER_HEADER.addtime,DOC_ORDER_HEADER.C_PROVINCE,DOC_ORDER_HEADER.C_CITY,DOC_ORDER_HEADER.MANUALFLAG,
                       DOC_ORDER_HEADER.C_DISTRICT,DOC_ORDER_HEADER.C_CONTACT,DOC_ORDER_HEADER.OrderNo,DOC_ORDER_HEADER.SOStatus,DOC_ORDER_HEADER.WAREHOUSEID,
-                      DOC_ORDER_HEADER.CustomerID,DOC_ORDER_HEADER.C_Tel2,DOC_ORDER_HEADER.C_Tel1,DOC_ORDER_HEADER.CarrierName,DOC_ORDER_HEADER.IssuePartyName,
+                      DOC_ORDER_HEADER.CustomerID,DOC_ORDER_HEADER.C_Tel2,DOC_ORDER_HEADER.C_Tel1,DOC_ORDER_HEADER.CarrierName,DOC_ORDER_HEADER.IssuePartyName,DOC_ORDER_HEADER.SOREFERENCE5,
                       DOC_ORDER_HEADER.EDIREMARKS2,DOC_ORDER_HEADER.WaveNo,DOC_ORDER_HEADER.SOReference1, NVL(ACT_ALLOCATION_DETAILS.PICKTOTRACEID,DOC_ORDER_HEADER.soreference5),
                       DOC_ORDER_HEADER.EDISENDFLAG2,DOC_ORDER_HEADER.EDISendTime2,DOC_ORDER_HEADER.Notes,DOC_ORDER_HEADER.ERPCANCELFLAG,
                       DOC_ORDER_HEADER.Picking_Print_Flag,DOC_ORDER_HEADER.EDISENDFLAG,DOC_ORDER_HEADER.ReleaseStatus,DOC_ORDER_HEADER.C_Address1,
@@ -1504,4 +1507,39 @@ sql;
             else $order->is_order_issue = false;
         }
     }
+
+    /**
+     * @param $orderno
+     * @return bool
+     * 一键回传 调用flux的sp
+     */
+    public function manualBack($orderno): bool
+    {
+        $who = 'WAS' . (Auth::user() ? '-' . Auth::user()["name"] : '');
+        $host=config('database.connections.oracle.host');
+        $serviceName=config('database.connections.oracle.service_name');
+        $user=config('database.connections.oracle.username');
+        $password=config('database.connections.oracle.password');
+        $conn=oci_connect($user,$password,$host.'/'.$serviceName,'utf8');
+        $IN_WarehouseID='';
+        $IN_OrderNo=$orderno;
+        $IN_Language='';
+        $IN_UserID=$who;
+        $OUT_Return_Code='';
+        $sql_sp="begin SPSOUDF_BS_ManualCF(:IN_WarehouseID,:IN_OrderNo,:IN_Language,:IN_UserID,:OUT_Return_Code); end;";
+        $stmt = oci_parse($conn, $sql_sp);
+        oci_bind_by_name($stmt,':IN_WarehouseID',$IN_WarehouseID);
+        oci_bind_by_name($stmt,':IN_OrderNo',$IN_OrderNo);
+        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,300);
+        oci_execute($stmt);
+
+        if (substr($OUT_Return_Code,0,3) != '000'){
+            app('LogService')->log(__METHOD__,'调用sp一键回传订单失败'.__FUNCTION__,"ORDERNO:".$orderno."ERROR:".$OUT_Return_Code);
+            return false;
+        }
+        oci_close($conn);
+        return true;
+    }
 }

+ 1 - 0
app/Services/OwnerPriceOperationService.php

@@ -546,6 +546,7 @@ class OwnerPriceOperationService
                 $package["price"] = $rule->unit_price;
                 $package["unitId"] = $rule->unit_id;
                 $package["fee_info"] = [];
+                //单位转换 数量匹配
                 switch ($units[$rule->unit_id]){
                     case "箱"://为箱时同步商品寻找箱规并改变商品数量
                         $pack = $this->changeUnit($ownerId,$package[$columnMapping[9]]);

+ 2 - 13
app/Services/StoreItemService.php

@@ -190,7 +190,7 @@ class StoreItemService
         foreach ($storeItems as $storeItem) {
             $commodity= $dataHandlerService->getKeyValue(['id'=>$storeItem->commodity_id],$commodities_map);if (!$commodity) continue;
             $asnDetail = $dataHandlerService
-                ->getKeyValue(['asnno' => $storeItem->store_asn_code, 'asnlineno' => $storeItem->asn_line_code,'customerid'=>$owner_map[$commodity->owner_id],'sku' => $commodity->sku], $asnDetails_map);
+                ->getKeyValue(['asnno' => $storeItem->store->asn_code ?? '', 'asnlineno' => $storeItem->asn_line_code,'customerid'=>$owner_map[$commodity->owner_id],'sku' => $commodity->sku], $asnDetails_map);
             if (!$asnDetail) {
                 array_push($delete_storeItems, $storeItem);
                 continue;
@@ -217,18 +217,7 @@ class StoreItemService
                 ];
             }
         }
-        if (count($updateParams) > 0) {
-            foreach (array_chunk($updateParams, 1000) as $item) {
-                try {
-                    $bool = $this->batchUpdate($item);
-                    if ($bool) {
-                        app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store_item success " . count($item) . ' || ' . json_encode($item));
-                    } else app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store_item FAILED " . ' || ' . json_encode($item));
-                } catch (\Exception $e) {
-                    app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store_item ERROR " . ' || ' . json_encode($updateParams) . ' || ' . json_encode($e->getMessage()) . ' || ' . json_encode($e->getTraceAsString()));
-                }
-            }
-        }
+        if (count($updateParams) > 1) $this->batchUpdate($updateParams);
         if (count($delete_storeItems) > 0) $this->deleteStoreItem($delete_storeItems);
         unset($updateParams, $asnDetails, $delete_storeItems);
     }

+ 4 - 15
app/Services/StoreService.php

@@ -223,18 +223,7 @@ class StoreService
                 ];
             }
         }
-        if (count($updateParams) > 1) {
-            foreach (array_chunk($updateParams, 1000) as $item) {
-                try {
-                    $bool=$this->batchUpdate($item);
-                    if ($bool) {
-                        app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store success " . count($item) . ' || ' . json_encode($item));
-                    } else app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store FAILED " . ' || ' . json_encode($item));
-                } catch (\Exception $e) {
-                    app('LogService')->log(__METHOD__, __FUNCTION__, "批量修改 store ERROR " . ' || ' . json_encode($updateParams) . ' || ' . json_encode($e->getMessage()) . ' || ' . json_encode($e->getTraceAsString()));
-                }
-            }
-        }
+        if (count($updateParams) > 1) $this->batchUpdate($updateParams);
         /** @var StoreItemService $storeItemService */
         $storeItemService = app(StoreItemService::class);
         $storeItemService->storeItemUpdateByWms($asnHerders);
@@ -330,12 +319,14 @@ class StoreService
         $GLOBALS["FEE_INFO"] = [];
         list($id,$money,$taxFee) = $service->matching($store, Feature::MAPPING["store"], $store->owner_id, "入库");
 
+        $amount = 0;
+        if ($store->storeItems)foreach ($store->storeItems as $item)$amount += $item->amount;
         if (!app("OwnerFeeDetailService")->create([
             "owner_id" => $store->owner_id,
             "worked_at" => $store->updated_at,
             "type" => "收货",
             "operation_bill" => $store->asn_code,
-            "commodity_amount" => array_sum(array_column($store->storeItems->toArray(), "amount")),
+            "commodity_amount" => $amount,
             "work_fee" => $money,
             "owner_price_operation_id" => $id,
             "created_at" => date('Y-m-d H:i:s'),
@@ -343,8 +334,6 @@ class StoreService
             "outer_table_name" => "stores",
             "work_tax_fee" => $taxFee,
         ])) return false;
-        $amount = 0;
-        if ($store->storeItems)foreach ($store->storeItems as $item)$amount += $item->amount;
         $this->setStoreAmount($store->owner_id,$amount);
         Cache::put("owner_fee_details:stores_".$store->id,1,86400);
         if ($money>0)$this->constructFeeInfo([

+ 34 - 30
app/Services/WorkOrderService.php

@@ -32,8 +32,9 @@ class WorkOrderService
      * 获取可生成工单的问题件类型
      * @return Builder[]|\Illuminate\Database\Eloquent\Collection
      */
-    public function getIssueType(){
-        return OrderIssueType::query()->whereIn('name',['拦截','信息更改','其他', '快递异常','错漏发','破损'])->get();
+    public function getIssueType()
+    {
+        return OrderIssueType::query()->whereIn('name', ['拦截', '信息更改', '其他', '快递异常', '错漏发', '破损'])->get();
     }
 
     /**
@@ -47,20 +48,20 @@ class WorkOrderService
         $work_order_types = [];
         $data = Carbon::now();
         $creator_id = Auth::user()['id'];
-        $parent = WorkOrderType::query()->firstOrCreate(['name' => '订单','prent_id' => 0,'level' => 1]);
+        $parent = WorkOrderType::query()->firstOrCreate(['name' => '订单', 'prent_id' => 0, 'level' => 1]);
         foreach ($params as $param) {
-            $order = Order::query()->where('code',$param['order_no'])->first();
+            $order = Order::query()->where('code', $param['order_no'])->first();
             $type_name = $param['order_issue_type'];
             if (!$param['order_issue_type']) {
                 $order_issue_type_id = 0;
                 $work_order_type_id = 0;
             } else {
-                if (!array_key_exists($type_name,$types)){
-                    $types[$type_name] = OrderIssueType::query()->where('name',$type_name)->first();
+                if (!array_key_exists($type_name, $types)) {
+                    $types[$type_name] = OrderIssueType::query()->where('name', $type_name)->first();
                     $work_order_type_name = $this->work_type_relation[$type_name] ?? $type_name;
-                    $work_order_types[$type_name] =  WorkOrderType::query()->firstOrCreate(
+                    $work_order_types[$type_name] = WorkOrderType::query()->firstOrCreate(
                         ['name' => $work_order_type_name],
-                        ['prent_id' =>$parent['id'],'table_name' => 'orders','level' => 2]
+                        ['prent_id' => $parent['id'], 'table_name' => 'orders', 'level' => 2]
                     );
                 }
                 $order_issue_type_id = $types[$type_name]['id'] ?? 0;
@@ -94,15 +95,15 @@ class WorkOrderService
                 'order_issue_type_id' => $order_issue_type_id ?? 0,
                 'uniquely_tag' => $order['code'] ?? null,
                 'status' => 1,
-                'created_at' =>  $data,
-                'updated_at' =>  $data,
+                'created_at' => $data,
+                'updated_at' => $data,
             ];
         }
-        if (isset($inner_params)){
+        if (isset($inner_params)) {
             WorkOrder::query()->insert($inner_params);
             return ['success' => true];
         }
-        return ['success' => false,'message' => '参数异常'];
+        return ['success' => false, 'message' => '参数异常'];
     }
 
     /**
@@ -112,12 +113,13 @@ class WorkOrderService
      */
     public function review($wordOrder): array
     {
-        $wordOrder->update(['reviewer_id' => Auth::user()['id'], 'review_at' => Carbon::now(), 'status' => 2,]);
-        $wordOrder = WorkOrder::query()->with(['type', 'creator', 'order' => function ($query) {
+        $wordOrder->update(['reviewer_id' => Auth::user()['id'], 'review_at' => Carbon::now(), 'status' => '2',]);
+        $workOrders = WorkOrder::query()->with(['type', 'creator', 'order' => function ($query) {
             /** @var $query Builder */
             $query->with('packages', 'issue', 'logistic');
-        }, 'reviewer'])->find($wordOrder['id']);
-        return ['success' => true, 'data' => $wordOrder];
+        }, 'reviewer'])->whereIn('id', [$wordOrder['id']])->get();
+        $this->tags($workOrders);
+        return ['success' => true, 'data' => $workOrders->first()];
     }
 
     /**
@@ -130,12 +132,13 @@ class WorkOrderService
         $ids = $workOrders->map(function ($item) {
             return $item->id;
         })->toArray();
-        WorkOrder::query()->whereIn('id', $ids)->update(['review_at' => Carbon::now(), 'reviewer_id' => Auth::user()['id']]);
-        $wordOrder = WorkOrder::query()->with(['type', 'creator', 'order' => function ($query) {
+        WorkOrder::query()->whereIn('id', $ids)->update(['review_at' => Carbon::now(), 'reviewer_id' => Auth::user()['id'], 'status' => '2']);
+        $wordOrders = WorkOrder::query()->with(['type', 'creator', 'order' => function ($query) {
             /** @var $query Builder */
             $query->with('packages', 'issue', 'logistic');
-        }, 'reviewer'])->find($ids);
-        return ['success' => true, 'data' => $wordOrder];
+        }, 'reviewer'])->whereIn('id', $ids)->get();
+        $this->tags($wordOrders);
+        return ['success' => true, 'data' => $wordOrders];
     }
 
 
@@ -153,8 +156,8 @@ class WorkOrderService
                 'result_explain' => $work_order->remark,
             ];
         }
-        if (!isset($inner_params)) return ['success' => false,'message' => '创建问题件失败'];
-        return  app('OrderIssueService')->buildOrderIssue($inner_params);
+        if (!isset($inner_params)) return ['success' => false, 'message' => '创建问题件失败'];
+        return app('OrderIssueService')->buildOrderIssue($inner_params);
     }
 
     /**
@@ -184,17 +187,18 @@ class WorkOrderService
      */
     public function tags(&$workOrders)
     {
-        $order_ids = $workOrders->map(function($item){
+        $order_ids = $workOrders->map(function ($item) {
             return $item->order_id;
         });
-        $order_issues = OrderIssue::query()->whereIn('order_id',$order_ids)->get();
+        $order_issues = OrderIssue::query()->whereIn('order_id', $order_ids)->get();
+
         foreach ($order_issues as $order_issue) {
             $codes[$order_issue->order_id] = true;
         }
-        if (!isset($codes))return;
+        if (!isset($codes)) return;
         foreach ($workOrders as &$workOrder) {
-            if (array_key_exists($workOrder->order_id,$codes))$workOrder->is_issue_order= true;
-            else  $workOrder->is_issue_order= false;
+            if (array_key_exists($workOrder->order_id, $codes)) $workOrder->is_issue_order = true;
+            else  $workOrder->is_issue_order = false;
         }
     }
 
@@ -205,8 +209,8 @@ class WorkOrderService
      */
     public function isIntercept($logistic_number): bool
     {
-        $package_query = OrderPackage::query()->select('order_id')->where('logistic_number',$logistic_number);
-         $order_issue_query = OrderIssueType::query()->select('id')->where('name','拦截');
-        return WorkOrder::query()->whereIn('order_id',$package_query)->whereIn('order_issue_type_id',$order_issue_query)->exists();
+        $package_query = OrderPackage::query()->select('order_id')->where('logistic_number', $logistic_number);
+        $order_issue_query = OrderIssueType::query()->select('id')->where('name', '拦截');
+        return WorkOrder::query()->whereIn('order_id', $package_query)->whereIn('order_issue_type_id', $order_issue_query)->exists();
     }
 }

+ 0 - 14
app/StoreItem.php

@@ -16,10 +16,6 @@ class StoreItem extends Model
         'store_id','asn_line_code','name',
         'sku','barcode','depository_id','amount','quality','status','commodity_id','expected_amount'
     ];
-    protected $appends=[
-        'store_asn_code',
-        'depository_name'
-    ];
 
     public function depository(){
         return $this->belongsTo('App\Depository','depository_id','id');
@@ -30,14 +26,4 @@ class StoreItem extends Model
     public function commodity(){
         return $this->hasOne('App\Commodity','id','commodity_id');
     }
-
-
-    public function getStoreASNCodeAttribute()
-    {
-        return $this['store']?$this['store']['asn_code']:null;
-    }
-    public function getDepositoryNameAttribute()
-    {
-        return $this['depository']?$this['depository']['name']:null;
-    }
 }

+ 140 - 0
app/Traits/LogisticSyncTrait.php

@@ -0,0 +1,140 @@
+<?php
+
+namespace App\Traits;
+
+use App\OrderPackage;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Str;
+use function DeepCopy\deep_copy;
+
+trait LogisticSyncTrait
+{
+    public function setExceptionStatus(array $data): array
+    {
+
+        $logistic_number = $data['logistic_number'];
+        /** @var OrderPackage $orderPackage */
+        $orderPackage = OrderPackage::query()
+            ->with(['order'])
+            ->where('logistic_number', $logistic_number)
+            ->first();
+        if ($orderPackage->exception_status === '单号异常' ||
+            $orderPackage->exception_status === '无法获取路由') {//这种类型的单,不需要再更新状态
+            return $data;
+        }
+
+        /**执行该方法时,默认没有异常,
+         *1. 之前有异常的件,
+         *  1.1 新的状态是无异常的可以更新为正常
+         *  1.2 新的状态是异常的可以更新为对应异常
+         *2. 之前无异常
+         *  2.1 新的状态无异常更新为无异常
+         *  2.2 新的状态异常更新为对应异常
+         */
+        $data['exception_status'] = '';
+        $created_at = Carbon::parse($orderPackage->created_at);
+        //当天的16:30
+        $transfer_status = $data['transfer_status'] ?? [];
+        if (empty($orderPackage->sent_at)) {//没复核
+            if (empty($transfer_status)) {//没有路由信息
+                //延迟发货
+                $created_at_clone = deep_copy($created_at);
+                if ($created_at->gt($created_at_clone->startOfDay()->addHours(16)->addMinutes(30))) {//下午16的单
+                    $created_at_clone = deep_copy($created_at);
+                    if ($created_at_clone->addDay()->endOfDay()->lt(now())) {//超过第二天的24时
+                        $created_at_clone = deep_copy($created_at);
+                        $data['exception_status'] = '延迟发货';
+                        $data['is_delay_deliver'] = true;
+                    }
+                } else {
+                    if ($created_at_clone->endOfDay()->lt(now())) {//超过当天的24时
+                        $data['exception_status'] = '延迟发货';
+                        $data['is_delay_deliver'] = true;
+                    }
+                }
+            } else {
+                //虚拟揽件
+//                $data['exception_status'] = '虚拟揽件'; //没有复核但是有路由信息   21-09-10 取消虚拟揽件状态
+            }
+        } else {//复核过
+            if (empty($transfer_status)) {//没有路由信息
+                /** @var Carbon $temp_time */
+                $temp_time = $orderPackage->weighed_at?:$orderPackage->sent_at;//揽收异常以称重时间优先 没有称重以发出时间
+                if (now()->gt($temp_time->addDay()->startOfDay()->addHours(6))) {//当前时间大于复核时间的第二天6点
+                    if (empty($orderPackage->weighed_at)) {//没有称重
+                        $data['exception_status'] = '疑似库内丢件';
+                    } else {//有称重
+                        $data['exception_status'] = '揽件异常';
+                    }
+                }
+            } else {//有路由信息
+                usort($transfer_status, function ($a, $b) {
+                    if ($a['accept_time'] === $b['accept_time']) {
+                        return 0;
+                    }
+                    return ($a['accept_time'] > $b['accept_time']) ? -1 : 1;
+                });
+
+                $last_transfer = $transfer_status[0]['accept_time'];
+                $last_remark = $transfer_status[0]['remark'];
+                if (count($transfer_status) <= 3) {//三条以内的不管地区 时间限制为24h
+                    if (Carbon::parse($last_transfer)->diffInHours(now()) > 24) {
+                        $data['exception_status'] = '在途异常';
+                    }
+                } else {
+                    $SHORT_RESPONSE_HOURS = (function ($province) {
+                        switch ($province) {
+                            case '浙江省':
+                            case '江苏省':
+                            case '上海':
+                            case '安徽省':
+                                return 24;
+                            case '北京':
+                            case '天津':
+                            case '江西省':
+                            case '湖北省':
+                            case '湖南省':
+                            case '广东省':
+                            case '福建省':
+                            case '山东省':
+                            case '河北省':
+                            case '河南省':
+                            case '山西省':
+                            case '四川省':
+                            case '陕西省':
+                            case '重庆':
+                            case '广西壮族自治区':
+                            case '贵州省':
+                            case '云南省':
+                            case '海南省':
+                            case '吉林省':
+                            case '黑龙江省':
+                            case '辽宁省':
+                                return 72;
+                            case '青海省':
+                            case '宁夏回族自治区':
+                            case '甘肃省':
+                            case '内蒙古自治区':
+                            case '新疆维吾尔自治区':
+                            case '西藏自治区':
+                                return 120;
+                            default:
+                                return 24;
+                        }
+                    })($orderPackage->order->province);
+                    if (Carbon::parse($last_transfer)->diffInHours(now()) > $SHORT_RESPONSE_HOURS) {
+                        $data['exception_status'] = '在途异常';
+                    }
+                }
+                if (Str::contains($last_remark,['代收','快递柜','驿站','自提柜','丰巢','快递小屋','合作点','快递超市'])) {
+                    $data['exception_status'] = '';
+                    $data['status'] = '已签收';
+                }
+                if ($data['exception_status']??''==='在途异常'&& $data['status']== '派送中') {
+                    $data['exception_status'] = '派送异常';
+                }
+            }
+        }
+        return $data;
+    }
+}

+ 0 - 14
app/WorkOrder.php

@@ -152,20 +152,6 @@ class WorkOrder extends Model
                 }
             }]);
         }]);
-//
-//        $query->with(['type','owner', 'creator', 'order' => function ($query) {
-//            /** @var $query Builder */
-//            $query->with(['packages','owner', 'issue'=>function($query){
-//                /** @var $query Builder */
-//                $query->with(['issueType','logs'=>function($query){
-//                    if (Gate::denies('订单管理-问题件-客户不可见')){
-//                        $query->with('user')->orderByDesc('created_at');
-//                    } else{
-//                        $query->with('user')->where('tag','=',0)->orderByDesc('created_at');
-//                    }
-//                }]);
-//            }, 'logistic']);
-//        }, 'reviewer','issueType']);
     }
 
 }

+ 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',
+            ]
+        ]
+    ]
 ];

+ 15 - 0
config/database.php

@@ -63,6 +63,21 @@ return [
             ]) : [],
         ],
 
+        'was_test' => [
+            'driver' => 'mysql',
+            'host' => '101.133.135.193',
+            'port' => '13306',
+            'database' => 'bswas_test',
+            'username' => 'bswas_test',
+            'password' => '123456',
+            'unix_socket' => '',
+            'charset' => 'utf8mb4',
+            'collation' => 'utf8mb4_unicode_ci',
+            'prefix' => '',
+            'strict' => false,
+            'engine' => null,
+        ],
+
         'mysql_haiRobotics' => [
             'driver' => 'mysql',
             'host' => '58.33.243.164',

+ 4 - 7
database/factories/OrderPackageFactory.php

@@ -7,9 +7,6 @@ use App\OrderPackage;
 use Faker\Generator as Faker;
 
 $factory->define(OrderPackage::class, function (Faker $faker) {
-    $statuses = ['无', '已称重', '已揽收', '在途', '在途异常', '派送中', '派送异常', '返回中', '返回异常', '返回派件', '其他异常', '已签收',];
-    $exceptions = ['是', '否'];
-    $exception_types = ['疑似库内丢件','揽件异常','中转异常','疑似丢件','派件异常','其他','无'];
     return [
         'logistic_number' => $faker->uuid,
         'order_id' => random_int(1, 10000),
@@ -21,15 +18,15 @@ $factory->define(OrderPackage::class, function (Faker $faker) {
         'paper_box_id' => random_int(1, 100),
         'measuring_machine_id' => random_int(1, 100),
         'weighed_at' => now()->subHours(3),
-        'status' => $faker->randomElement($statuses),
+        'status' => random_int(1,8),
         'sent_at' => now()->subHours(1),
         'received_at' => null,
-        'exception' => $faker->randomElement($exceptions),
         'transfer_status' => null,
         'remark' => null,
         'owner_id' => random_int(1, 100),
         'uploaded_to_wms' => '是',
-        'exception_message' => $faker->name,
-        'exception_type' => $faker->randomElement($exception_types),
+        'sync_routes_flag' => false,
+        'is_manual_update' => false,
+        'exception_status' => random_int(1,6),
     ];
 });

+ 32 - 0
database/migrations/2021_09_06_095009_change_column_to_work_orders.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ChangeColumnToWorkOrders extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('work_orders', function (Blueprint $table) {
+            $table->integer('owner_id')->comment('货主')->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('work_orders', function (Blueprint $table) {
+            $table->tinyInteger('owner_id')->comment('货主')->change();
+        });
+    }
+}

+ 32 - 0
database/migrations/2021_09_06_135431_add_is_intercept_to_order_issues.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddIsInterceptToOrderIssues extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_issues', function (Blueprint $table) {
+            $table->tinyInteger('is_intercept')->comment('是否库内拦截');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_issues', function (Blueprint $table) {
+            $table->dropColumn('is_intercept');
+        });
+    }
+}

+ 34 - 0
database/migrations/2021_09_09_154053_add_column_exception_type_to_order_packages_table.php

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddColumnExceptionTypeToOrderPackagesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->integer('exception_status')->default(0)->comment('异常状态');
+            $table->boolean('is_delay_deliver')->default(false)->comment('是否延迟发货');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->dropColumn('exception_status');
+            $table->dropColumn('is_delay_deliver');
+        });
+    }
+}

+ 42 - 0
database/migrations/2021_09_11_142547_add_index_to_order_packages_table.php

@@ -0,0 +1,42 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddIndexToOrderPackagesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->dropIndex('order_packages_express_index');
+        });
+
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->index(['sent_at', 'order_id', 'status', 'exception_status', 'received_at', 'sync_routes_flag'], 'order_packages_express_index');
+
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->dropIndex('order_packages_express_index');
+
+        });
+
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->index(['sent_at', 'order_id', 'status', 'received_at', 'sync_routes_flag'], 'order_packages_express_index');
+        });
+    }
+}

+ 42 - 0
database/migrations/2021_09_11_163234_add_index_created_at_to_order_packages_table.php

@@ -0,0 +1,42 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddIndexCreatedAtToOrderPackagesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->dropIndex('order_packages_express_index');
+        });
+
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->index(['created_at', 'order_id', 'status', 'exception_status', 'received_at', 'sync_routes_flag'], 'order_packages_express_index');
+
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->dropIndex('order_packages_express_index');
+
+        });
+
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->index(['sent_at', 'order_id', 'status', 'exception_status','received_at', 'sync_routes_flag'], 'order_packages_express_index');
+        });
+    }
+}

+ 1 - 0
resources/views/maintenance/user/create.blade.php

@@ -338,6 +338,7 @@
 
                 workGroup: [@foreach($workGroup as $wg)@json($wg),@endforeach],
                 ownerGroup: [@foreach($ownerGroup as $group)@json($group),@endforeach],
+                ownerGroups: []
             },
             components:{
                 'tree':"url:{{asset("js/vue/tree.vue")}}"

+ 91 - 2
resources/views/order/index/delivering.blade.php

@@ -39,6 +39,10 @@
                     @can('订单管理-订单-生成工单')
                         <button class="btn btn-sm ml-1 btn-outline-success" @click="showInterceptModel()">生成工单</button>
                     @endcan
+                    @can('订单管理-订单-一键回传')
+                        <button class="btn btn-sm ml-1 btn-success tooltipTarget" title="订单一键回传必须满足条件:订单状态为“分配完成,部分拣货,拣货完成,播种完成”;订单未冻结;订单有快递单号"
+                                @click="manualBack()">一键回传</button>
+                    @endcan
                 </div>
                 <div class="modal fade " style="top: 20%" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                     <div class="modal-dialog">
@@ -73,8 +77,8 @@
                         <td class="text-muted text-nowrap"><span>@{{ order.carriername }}</span></td>
                         <td class="text-nowrap">
                             <div v-if="picktotraceidMap[order.orderno] && picktotraceidMap[order.orderno].length>1" class="text-center">
-                                <span v-for="picktotraceid in picktotraceidMap[order.orderno]" v-if="order.is_unfold">
-                                    @{{ picktotraceid }}<br>
+                                <span v-for="(picktotraceid,key) in picktotraceidMap[order.orderno]" v-if="order.is_unfold">
+                                    @{{ isDB(order.carriername) ? (order.code5+'#'+(key+1)) : picktotraceid }}<br>
                                 </span>
                                 <button class="btn btn-sm btn-outline-info" :style="order.is_unfold ? 'opacity:0.7' : ''" @click="isUnfold(order)">
                                     <span v-if="order.is_unfold" class="mt-1">收起</span>
@@ -117,6 +121,7 @@
                             </div>
                         </td>
                         <td><span>@{{ order.notes }}</span></td>
+                        <td><span>@{{ order.manualflag}}</span></td>
                         <td><span>@{{ order.erpcancelflag }}</span></td>
                         <td><span>@{{ order.picking_print_flag }}</span></td>
                         <td><span>@{{ order.edisendflag }}</span></td>
@@ -354,6 +359,7 @@
                     ],
                     [
                         {name:'restrict_time',type:'select',tip:'查询限定时间范围',placeholder:'查询时间范围',data:[{name:'1',value:'一天内'},{name:'7',value:'一周内'},{name:"30",value:"一月内"},{name:"90",value:"本季度"}]},
+                        {name:'manualflag',type:'select',tip:'是否人工回传',placeholder:'是否人工回传',data:[{name:'Y',value:'是'},{name:'N',value:'否'}]},
                     ],
                 ];
                 this.form = new query({
@@ -392,6 +398,7 @@
                             {value:"复核时间",col:"2"}
                         ]},
                     {name:'notes',value: '备注'},
+                    {name:'manualflag',value: '人工回传标记'},
                     {name:'erpcancelflag',value: '接口取消标记'},
                     {name:'picking_print_flag',value: '拣货单打印标记'},
                     {name:'edisendflag',value: '接口回传标记'},
@@ -1007,6 +1014,88 @@
                         window.tempTip.show(err)
                     });
                 },
+                changeReceiveInfo() {
+                    let url = '{{url('apiLocal/workOrder/editOrderReceiveInfo')}}';
+                    let data = {
+                        order_nos:checkData[0],
+                        grad:this.grad,
+                        remake:`${this.remark.name} ${this.remark.phone} ${this.remark.province} ${this.remark.city} ${this.remark.city} ${this.remark.district} ${this.remark.adder}`,
+                    };
+                    console.log(data);
+                    window.tempTip.setIndex('1999');
+                    window.axios.post(url,data).then(res=>{
+                        if (res.data.success){
+                            window.tempTip.showSuccess('生成修改工单成功');
+                            $('#intercept-modal').modal('hide');
+                        } else{
+                            window.tempTip.show(res.data.message);
+                        }
+                    }).catch(err=>{
+                        window.tempTip.show(err);
+                    });
+                },
+                manualBack(){
+                    let _this=this;
+                    let orders=[];
+                    let fail=[];
+                    let isGreater=false;
+                    const start = new Date(new Date(new Date().toLocaleDateString()).getTime()+16*60*60*1000+30*60*1000);
+                    if(checkData.length===0){tempTip.show('没有勾选记录');return;}
+                    _this.orders.forEach(function(order){
+                        if (new Date(new Date(order.addtime).getTime())>start) isGreater=true;
+                        checkData.forEach(function (checkedId) {
+                            if(order.orderno===checkedId){
+                                if (order.soreference5 //存在快递单号
+                                    && order.releasestatus!='H' //订单未冻结
+                                    && order.manualflag=='N' //订单未回传
+                                    && (order.sostatus=='40' ||
+                                        order.sostatus=='50' ||
+                                        order.sostatus=='60' ||
+                                        order.sostatus=='61')) //订单状态为 分配完成,部分拣货,拣货完成,或播种完成
+                                {orders.push(order.orderno);}else {fail.push(order.orderno)}
+                            }
+                        });
+                    });
+                    let failText='';
+                    fail.forEach(function (item){
+                        failText += item + ','
+                    });
+                    if (isGreater){
+                        if (!confirm('订单中包含16:30以后推送的订单,有超时揽收风险,是否确定操作?')) return;
+                    }else {
+                        if (!confirm('提前回传订单将无法取消,是否确定操作?')) return;
+                    }
+                    let url = '{{url('order/manualBack')}}';
+                    window.axios.post(url, {ordernos:orders})
+                        .then(res => {
+                            if (res.data.success) {
+                                _this.orders.forEach(function (order){
+                                    res.data.successNo.forEach(function (success_item){
+                                        if (order.orderno==success_item)order.manualflag='Y';
+                                    })
+                                })
+                                res.data.failNo.forEach(function (item){
+                                    failText += item + ','
+                                });
+                                if (failText.length > 0) {
+                                    failText = failText.substr(0,failText.length - 1);
+                                }
+                                window.tempTip.setDuration(4000);
+                                window.tempTip.showSuccess('回传成功!'+'    单号:'+failText+'不满足回传条件,系统已自动筛除');
+                                this.$forceUpdate();
+                                return;
+                            }
+                            window.tempTip.setDuration(3000);
+                            window.tempTip.show('人工回传失败');
+                        }).catch(err => {
+                        window.tempTip.setDuration(3000);
+                        window.tempTip.show("网络错误:" + err);
+                    })
+                },
+                isDB(item){
+                    if(item.indexOf('德邦') == -1  || item.indexOf('京东') == -1) return false;
+                    return  true;
+                }
             },
         });
     </script>

+ 7 - 1
resources/views/order/issue/index.blade.php

@@ -228,6 +228,7 @@
                                 @else
                                     <span v-if="orderIssue.is_new_rejecting">@{{ orderIssue.is_new_rejecting }}</span>
                                 @endcan
+                                <span class="badge badge-info" v-if="orderIssue.is_intercept === 1">库内拦截</span>
                             </td>
                             @can("订单管理-问题件-置顶")
                                 <td class="text-muted child-layer-1">
@@ -300,7 +301,7 @@
                             <template v-if="orderIssue.order">
                                 <span :class="orderIssue.order.packages.length > 1 ?'collapse ':''"
                                       :id="'logisticNumbers'+orderIssue.id">
-                                    <span class="m-0 p-0 d-inline-block" v-for="package in orderIssue.order.packages">@{{ package.logistic_number!==orderIssue.order.code ? package.logistic_number:'' }}&nbsp;&nbsp;</span>
+                                    <span class="m-0 p-0 d-inline-block" v-for="(package,key) in orderIssue.order.packages">@{{ (orderIssue.custom_code && isDB(orderIssue.order.logistic_id)) ? orderIssue.custom_code +'-'+(key+1) : (package.logistic_number!==orderIssue.order.code ? package.logistic_number:'') }}&nbsp;&nbsp;</span>
                                 </span>
                                 <button type="button" class="btn btn-sm btn-outline-primary align-middle mt-1"
                                     v-if="orderIssue.order.packages.length > 1"
@@ -2178,6 +2179,11 @@
                         window.tempTip.show(err);
                     });
                 },
+                isDB(item){
+                    let arr = [14,15,28,29,72,87,121];
+                    if(arr.indexOf(item) >= 0) return true
+                    return  false;
+                }
             },
             filters:{
                 date:function(value) {

+ 58 - 23
resources/views/order/workOrder/index.blade.php

@@ -65,6 +65,7 @@
                                             审核
                                         </button>
                                     @endcan
+
                                 </td>
                                 <td class="text-center">@{{ item.status }}</td>
                                 <td class="text-center">@{{ item.owner ? item.owner.name : '' }}</td>
@@ -196,7 +197,15 @@
                                 <td class="text-center">@{{ item.created_at }}</td>
                                 <td>@{{ item.reviewer ? item.reviewer.name : ''}}</td>
                                 <td>@{{ item.review_at }}</td>
+                                @can('订单管理-工单处理-删除')
+                                    <td>
+                                        <button class="btn btn-sm btn-outline-danger"
+                                                @click="destroy(item,i)">
+                                            删除
+                                        </button>
+                                    </td>
 
+                                @endcan
                             </tr>
                         </template>
                         </tbody>
@@ -265,6 +274,7 @@
                         tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的承运商'],
                         placeholder: ['承运商', '定位或多选承运商']
                     },
+                    @can('订单管理-订单问题件生成')
                     {
                         name: 'owner',
                         type: 'select_multiple_select',
@@ -272,16 +282,8 @@
                         tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的货主'],
                         placeholder: ['货主', '定位或多选货主']
                     },
+                    @endcan
                     {name: 'logistic_number', type: 'input', placeholder: '快递单号'},
-                    {
-                        name: 'grad',
-                        type: 'select',
-                        placeholder: '工单等级',
-                        data: [{name: 1, value: '一般'}, {name: 2, value: '重要'}, {name: 3, value: '紧急'}, {
-                            name: 4,
-                            value: '重要且紧急'
-                        },]
-                    },
                     {
                         name: 'is_issue_order',
                         type: 'select',
@@ -302,27 +304,30 @@
                 let column = [
                     {name: 'no', value: '序号', neglect: true},
                     {name: 'operation', value: '操作', neglect: true},
-                    {name: 'status', value: '状态'},
-                    {name: 'owner', value: '货主'},
-                    {name: 'client_code', value: '订单号'},
-                    {name: 'logisticName', value: '承运商'},
+                    {name: 'status', value: '状态',neglect: true},
+                    {name: 'owner', value: '货主',neglect: true},
+                    {name: 'client_code', value: '订单号',neglect: true},
+                    {name: 'logisticName', value: '承运商',neglect: true},
                     {name: 'logisticNumber', value: '快递单号'},
                     {name: 'issueType', value: '问题件类型'},
-                    {name: 'workOrderInfo', value: '问题描述'},
-                    {name: 'result_explain', value: '情况说明'},
+                    {name: 'workOrderInfo', value: '问题描述',neglect: true},
+                    {name: 'result_explain', value: '情况说明',neglect: true},
                     {name: 'orderIssueType', value: '问题件类别'},
                     {
                         name: 'orderIssueProcessLogs', type: 'multi', title: "处理结果", rows: [
                             {value: "内容", col: "4"},
                             {value: "操作人", col: "4"},
                             {value: "时间", col: "4"},
-                        ]
+                        ],neglect: true
                     },
                     {name: 'Info', value: '物流跟踪信息', neglect: true},
-                    {name: 'creator', value: '创建人'},
-                    {name: 'submit_at', value: '提交时间'},
-                    {name: 'reviewer', value: '审核人'},
-                    {name: 'review_at', value: '审核时间'},
+                    {name: 'creator', value: '创建人',neglect: true},
+                    {name: 'submit_at', value: '提交时间',neglect: true},
+                    {name: 'reviewer', value: '审核人',neglect: true},
+                    {name: 'review_at', value: '审核时间',neglect: true},
+                    @can('订单管理-工单处理-删除')
+                    {name: 'delete_operation', value: '其他操作',neglect: true},
+                    @endcan()
                 ];
 
                 new Header({
@@ -401,6 +406,7 @@
                     else data.ids = checkData;
                     if (!confirm('是否生成对应的问题件')) return;
                     let _this = this;
+                    window.tempTip.waitingTip('生成中........');
                     window.axios.post(url, data).then(res => {
                         if (res.data.success) {
                             res.data.data.forEach(item => {
@@ -412,11 +418,14 @@
                                 });
                             });
                             this.$forceUpdate();
+                            window.tempTip.cancelWaitingTip();
                             window.tempTip.showSuccess('已生成对应的问题件');
                         } else {
+                            window.tempTip.cancelWaitingTip();
                             window.tempTip.show(res.data.message ? res.data.message : '生成问题件异常');
                         }
                     }).catch(err => {
+                        window.tempTip.cancelWaitingTip();
                         window.tempTip.show(err)
                     });
                 },
@@ -445,7 +454,8 @@
                     if (!item.order) return '';
                     if (!item.order.packages) return '';
                     let message = '';
-                    switch (item.issue_order_type) {
+                    let issue_type = item.issue_type? item.issue_type.name : '';
+                    switch (issue_type) {
                         case '拦截':
                             message = this.interceptMessage(item);
                             break;
@@ -482,6 +492,7 @@
                     let logistic_code = item.order.logistic.code;
                     let adder = item.order.consignee_name + ' ' + item.order.consignee_phone + ' '
                         + item.order.province + ' ' + item.order.city + ' ' + item.order.district + ' ' + item.order.address;
+
                     item.order.packages.forEach(node => {
                         if (logistic_code.includes('SF')) { // 顺丰订单
                             message += node.logistic_number + ' ——改信息: ' + item.remark + ',运费到付或月结' + '\n';
@@ -525,6 +536,7 @@
                     let _this = this;
                     window.tempTip.setIndex('1999');
                     if (!confirm('是否对当前选中订单进行审核')) return;
+                    window.tempTip.waitingTip('审核中........');
                     window.axios.post(url, data).then(res => {
                         if (res.data.success) {
                             $.each(res.data.data, (i, data) => {
@@ -535,11 +547,14 @@
                                 });
                             });
                             this.$forceUpdate();
+                            window.tempTip.cancelWaitingTip();
                             window.tempTip.showSuccess('审核完成');
                         } else {
+                            window.tempTip.cancelWaitingTip();
                             window.tempTip.show(res.data.message ? res.data.message : '审核出现异常');
                         }
                     }).catch(err => {
+                        window.tempTip.cancelWaitingTip();
                         window.tempTip.show(err);
                     })
                 },
@@ -549,14 +564,18 @@
                         id: item.id,
                         type_id: $(e.target).val()
                     };
+                    window.tempTip.waitingTip('修改中.........');
                     window.axios.post(url, data).then(res => {
                         if (res.data.success) {
+                            window.tempTip.cancelWaitingTip();
                             window.tempTip.showSuccess('修改成功');
                             item.order_issue_type_id = data.type_id;
                         } else {
+                            window.tempTip.cancelWaitingTip();
                             window.tempTip.show(res.data.message ? res.data.message : '修改异常');
                         }
                     }).catch(err => {
+                        window.tempTip.cancelWaitingTip();
                         window.tempTip.show(err);
                     });
                 },
@@ -582,7 +601,6 @@
                     window.axios.post(url, data).then(res => {
                         if (res.data.success) {
                             window.tempTip.showSuccess('修改问题件类型成功');
-
                             res.data.data.forEach(item => {
                                 _this.sortOrder(item);
                                 _this.workOrders.forEach((workOrder, i, array) => {
@@ -600,7 +618,24 @@
                         window.tempTip.show(err)
                     })
                 },
-
+                destroy(item,i){
+                    let url = '{{url('apiLocal/workOrder/')}}'+'/'+item.id;
+                    if(!confirm('是否删除当前工单')) return ;
+                    window.tempTip.waitingTip('删除.........');
+                    window.axios.delete(url).then(res=>{
+                        if (res.data.success){
+                            this.$delete(this.workOrders,i);
+                            window.tempTip.cancelWaitingTip();
+                            window.tempTip.showSuccess('删除成功');
+                        }else {
+                            window.tempTip.cancelWaitingTip();
+                            window.tempTip.show(res.data.message ? res.data.message : '');
+                        }
+                    }).catch(err=>{
+                        window.tempTip.cancelWaitingTip();
+                        window.tempTip.show(err);
+                    })
+                }
             },
         });
     </script>

+ 98 - 32
resources/views/package/logistic/index.blade.php

@@ -92,6 +92,17 @@
                         </button>
                     </span>
 
+                    <span class="ml-1">
+                        <select class="form-control-sm ml-2" v-model="batchExceptionStatus">
+                            <option v-for="(value,index) in exception_statuses" :value="value"
+                                    :name="value" :key="index">@{{ value }}
+                            </option>
+                        </select>
+                        <button @click="batchExceptionStatusUpdate()" type="button"
+                                class="btn btn-sm ml-2 btn-outline-danger">批量异常状态修改
+                        </button>
+                    </span>
+
                     <span class="ml-1">
                         <!-- Button trigger modal -->
                         <button
@@ -115,23 +126,35 @@
                         <input class="checkItem" type="checkbox" :value="package.logistic_number">
                     </td>
                     <td>
-                        <span style="position:relative">
+                        <span style="position:relative;line-height: 12px">
                             @{{ i+1 }}
-                            <span class="badge badge-danger" v-if="package.order.issue">问题件</span>
+                            <!--          是否同步过                  -->
                             <span
                                 style="display: inline-block;width: 15px;height: 15px;border-radius: 50%;position: relative;top: 3px; margin-left: 3px;box-shadow: 0 0 3px #211f1f"
-                                  :style="package.sync_routes_flag?'background-color:#4ed32d':'background-color:#e83939'"></span>
+                                :style="package.sync_routes_flag?'background-color:#4ed32d':'background-color:#e83939'"></span>
+                            <!--               是否为问题件         -->
+                            <span class="badge badge-danger" v-if="package.order.issue">?</span>
+
+<!--       是否手动修改                     -->
                             <span v-if="package.is_manual_update">
                                 <i class="fa fa-hand-paper-o" aria-hidden="true"
                                    style="color: red;margin-left: 5px"></i>
                             </span>
+<!--     延时发货图标                       -->
+                            <span
+                                v-if="package.is_delay_deliver"
+                                style="margin-left: 5px">
+                                <i class="fa fa-circle-o-notch fa-spin"></i>
+                            </span>
                         </span>
                     </td>
-                    <td>@{{ package.logistic_number }}</td>
+                    <td :style="package.exception_status=='单号异常'?'color:red':''">@{{ package.logistic_number }}</td>
                     <td>@{{ package.status }}</td>
+                    <td>@{{ package.exception_status }}</td>
                     <td>@{{ package.order != null ? package.order.logistic.name : '#' }}</td>
                     <td>@{{ package.order != null ? package.order.owner.name : '#' }}</td>
                     <td>@{{ package.order != null ? package.order.province : '#' }}</td>
+                    <td>@{{ package.created_at }}</td>
                     <td>@{{ package.sent_at }}</td>
                     <td>@{{ package.received_at }}</td>
                     <td>@{{ package.weighed_at }}</td>
@@ -267,22 +290,27 @@
                 showRemarkList: {},
                 selectTr: 0,
                 statuses: [
-                    '无',
+                    '生成订单',
+                    '已复核',
                     '已称重',
-                    '已揽收',
-                    '揽件异常',
-                    '疑似库内丢件',
+                    '已揽件',
                     '在途',
-                    '在途异常',
                     '派送中',
-                    '派送异常',
-                    '返回中',
-                    '返回异常',
-                    '返回派件',
-                    '其他异常',
                     '已签收',
+                    '其他',
+                    '返回中',
+                ],
+                exception_statuses: [
+                    '单号异常',
+                    '无法获取路由',
+                    '延迟发货',
+                    '疑似库内丢件',
+                    '在途异常',
+                    '揽件异常',
+                    '派送异常'
                 ],
                 batchStatus: null,
+                batchExceptionStatus: null,
                 remarkHover: null,
                 remark: null,
                 isShowRemarkInput: false,
@@ -319,20 +347,15 @@
                             tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的状态'],
                             placeholder: ['状态','定位或多选状态'],
                             data: [
-                                {name: '1', value: '无'},
-                                {name: '2', value: '已称重'},
-                                {name: '3', value: '已揽收'},
-                                {name: '4', value: '揽件异常'},
-                                {name: '5', value: '疑似库内丢件'},
-                                {name: '6', value: '在途'},
-                                {name: '7', value: '在途异常'},
-                                {name: '8', value: '派送中'},
-                                {name: '9', value: '派送异常'},
-                                {name: '10', value: '返回中'},
-                                {name: '11', value: '返回异常'},
-                                {name: '12', value: '返回派件'},
-                                {name: '13', value: '其他异常'},
-                                {name: '14', value: '已签收'},
+                                {name: '1', value: '生成订单'},
+                                {name: '2', value: '已复核'},
+                                {name: '3', value: '已称重'},
+                                {name: '4', value: '已揽件'},
+                                {name: '5', value: '在途'},
+                                {name: '6', value: '派送中'},
+                                {name: '7', value: '已签收'},
+                                {name: '8', value: '其他'},
+                                {name: '9', value: '返回中'},
                             ]
                         },
                         {name: 'sent_at_start', type: 'dateTime', tip: '选择显示发出时间的起始时间'},
@@ -344,8 +367,17 @@
                             data: [{name: false, value: '无'}, {name: true, value: '已称重'}]
                         },
                         {name: 'received_at_start', type: 'dateTime', tip: '选择显示收货时间的起始时间'},
-                        {name: 'default_date', type: 'checkbox', tip: '默认15天', data: [{name: 'ture', value: '默认15天'}]},
-                        {name: 'default_logistics', type: 'checkbox', tip: '默认承运商', data: [{name: 'ture', value: '默认承运商'}]},
+                        {
+                            name: 'is_customer_service_remark',
+                            type: 'select',
+                            tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的状态'],
+                            placeholder: ['客服备注'],
+                            data: [
+                                {name: '是', value: '是'},
+                                {name: '否', value: '否'},
+                            ]
+                        },
+                        {name: 'customer_service_remark_created_at_start', type: 'dateTime', tip: '选择显示客服备注时间的起始时间'},
                     ],
                     [
                         {
@@ -376,7 +408,6 @@
                             placeholder: '是否有查询记录',
                             data: [{name: true, value: '是'}, {name: false, value: '否'}]
                         },
-
                         {name: 'sent_at_end', type: 'dateTime', tip: '选择显示发出时间的截止时间'},
                         {
                             name: 'is_issue',
@@ -393,6 +424,7 @@
                             placeholder: '退件状态',
                             data: [{name: '无', value: '无'}, {name: '有', value: '有'}]
                         },
+                        {name: 'customer_service_remark_created_at_end', type: 'dateTime', tip: '选择显示客服备注时间的起始时间'},
                     ],
                     [
                         {
@@ -421,7 +453,23 @@
                             ]
                         },
                         {name: 'order_notes', type: 'input', tip: '糊模查找需要在右边打上%符号', placeholder: '订单备注'},
-
+                        {
+                            name: 'exception_status',
+                            type: 'select_multiple_select',
+                            tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的异常'],
+                            placeholder: ['异常', '定位或多选异常'],
+                            data: [
+                                {name: '1', value: '单号异常'},
+                                {name: '2', value: '无法获取路由'},
+                                {name: '3', value: '延迟发货'},
+                                {name: '4', value: '疑似库内丢件'},
+                                {name: '5', value: '在途异常'},
+                                {name: '6', value: '揽件异常'},
+                                {name: '7', value: '派送异常'},
+                            ]
+                        },
+                        {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({
@@ -434,9 +482,11 @@
                     {name: 'index', value: '序号', neglect: true},
                     {name: 'logistic_number', value: '单号'},
                     {name: 'status', value: '状态'},
+                    {name: 'exception_status', value: '异常状态'},
                     {name: 'logistic_name', value: '快递公司'},
                     {name: 'owner_name', value: '货主'},
                     {name: 'province', value: '省份'},
+                    {name: 'created_at', value: '订单生成日期'},
                     {name: 'sent_at', value: '发出日期'},
                     {name: 'received_at', value: '收货日期'},
                     {name: 'weighed_at', value: '称重日期'},
@@ -498,6 +548,22 @@
                         location.reload();
                     })
                 },
+                batchExceptionStatusUpdate() {
+                    if(!confirm('是否却认操作')) return;
+                    let _this = this;
+                    if (checkData.length === 0) {
+                        tempTip.show('没有勾选记录');
+                        return
+                    }
+                    axios.put('{{url('package/logistic/batchUpdate')}}', {
+                        exceptionStatus: this.batchExceptionStatus,
+                        logistic_numbers: checkData
+                    }).then(() => {
+                        tempTip.setDuration(1000);
+                        tempTip.showSuccess('批量异常状态成功');
+                        location.reload();
+                    })
+                },
                 submitBenchRemark() {
                     let _this = this;
                     if (checkData.length === 0) {

+ 15 - 139
resources/views/store/deliveryAppointment/list.blade.php

@@ -16,76 +16,31 @@
             @can("入库管理-入库预约-质检")<button type="button" class="btn btn-outline-primary" @click="qualityInspectionMark()">质检</button>@endcan
         </div>
         <table class="table table-striped table-bordered table-hover text-nowrap td-min-width-80" id="table">
-<!--            <tr class="text-center">
-                <th>
-                    <label for="all" id="cloneCheckAll">
-                        <input id="all" type="checkbox" @click="checkAll($event)">全选
-                    </label>
-                </th>
-                <th>序号</th>
-                <th>操作</th>
-                <th>状态</th>
-                <th>预约号</th>
-                <th>ASN单号</th>
-                <th>预约时间</th>
-                <th>创建时间</th>
-                <th>操作/送达时间</th>
-                <th>货主</th>
-                <th>重量/吨</th>
-                <th>体积/立方</th>
-                <th>箱数</th>
-                <th>备注</th>
-                <th>车号/快递公司</th>
-                <th>车型/快递单号</th>-->
-<!--                <th>仓库</th>
-                <th>
-                    <div class="row" style="min-width: 800px">
-                        <div class="col-12">车辆信息</div>
-                    </div>
-                    <div class="row">
-                        <div class="col-2">预约号</div>
-                        <div class="col-2">车牌号</div>
-                        <div class="col-2">车型</div>
-                        <div class="col-1">司机姓名</div>
-                        <div class="col-2">司机电话</div>
-                        <div class="col-3">操作/送达时间</div>
-                    </div>
-                </th>
-                <th>快递公司</th>
-                <th>快递单号</th>
-                <th>采购单号</th>
-                <th>
-                    <div class="row">
-                        <div class="col-12 text-center">明细单</div>
-                    </div>
-                    <div class="row" style="min-width: 500px">
-                        <div class="col-5 text-center">商品名称</div>
-                        <div class="col-4 text-center">条码</div>
-                        <div class="col-2 text-center">数量</div>
-                    </div>
-                </th>-->
-<!--            </tr>-->
             <tr v-for="(info,i) in list" :id="'info-'+i">
                 <td><input class="checkItem" type="checkbox" :value="list.id"></td>
                 <td>@{{ i+1 }}</td>
                 <td>
                     <span>
-                         @can("入库管理-入库预约-预约管理-签到")<span v-if="(info.status==0 && info.appointment_date==today) && info.cars[0].status==0"><button class="btn btn-sm btn-outline-success" @click="signIn(i,0)">签到</button><br></span>@endcan
-                        <span v-if="info.status==0">
-                            <button type="button" @click="cancel(info.id,i)" class="btn btn-sm btn-outline-danger">取消预约</button><br>
-                            <button type="button" @click="updateDeliveryDate(info,i)" class="btn btn-sm btn-outline-primary">修改预约</button>
+                        <span v-if="info.cars[0].status==0">
+                            @can("入库管理-入库预约-预约管理-签到")
+                                <span v-if="info.status==0 || info.status==3"><button class="btn btn-sm btn-outline-success" @click="signIn(i,0)">签到</button><br></span>
+                            @endcan
+                            <span v-if="info.status==0">
+                                <button type="button" @click="cancel(info.id,i)" class="btn btn-sm btn-outline-danger">取消预约</button><br>
+                                <button type="button" @click="updateDeliveryDate(info,i)" class="btn btn-sm btn-outline-primary">修改预约</button>
+                            </span>
+                             <span v-if="info.status==3">
+                                 <button type="button" @click="reschedule(info,i)" class="btn btn-sm btn-outline-primary">重新预约</button>
+                             </span>
                         </span>
-                        <span v-if="info.status==2">
+                        <span v-if="info.status==2 || info.status==4">
                             <button type="button" @click="printReceipt(info)" class="btn btn-sm btn-outline-success"><i class="fa fa-print"></i>&nbsp;打印</button>
                         </span>
-                         <span v-if="info.status==3">
-                             <button type="button" @click="reschedule(info,i)" class="btn btn-sm btn-outline-primary">重新预约</button>
-                         </span>
-                         <span v-if="info.details.length>0">
+                        <span v-if="info.details.length>0">
                              <br>
                              <button class="btn btn-sm btn-dark" v-if="currentIndex===i" @click="openDetails(i,true);">关闭明细</button>
                              <button class="btn btn-sm btn-outline-info" v-else  @click="openDetails(i);">查看明细</button>
-                         </span>
+                        </span>
                     </span>
                 </td>
                 <td>
@@ -129,68 +84,6 @@
                 <td><div class="text-overflow-replace-200">@{{ info.remark }}</div></td>
                 <td>@{{ info.logistic ? info.logistic.name : info.cars[0].license_plate_number }}</td>
                 <td>@{{ info.logistic ? info.logistic_number : (info.cars[0].car ? info.cars[0].car.name : '') }}</td>
-
-<!--                <td>
-                    <label v-if="!poolMapping.warehouses"></label>
-                    <label v-else>@{{ poolMapping.warehouses[info.warehouse_id] }}</label>
-                </td>
-                <td>
-                    <div v-if="info.cars.length>0" class="text-center">
-                        <div class="row">
-                            <div class="col-2 font-weight-bold">@{{ info.cars[0].appointment_number }}</div>
-                            <div class="col-2 text-secondary">@{{ info.cars[0].license_plate_number }}</div>
-                            <div class="col-2 text-secondary">@{{ info.cars[0].car ? info.cars[0].car.name : '' }}</div>
-                            <div class="col-1 text-secondary">@{{ info.cars[0].driver_name }}</div>
-                            <div class="col-2 text-secondary">@{{ info.cars[0].driver_phone }}</div>
-                            <div class="col-3">
-                                @can("入库管理-入库预约-预约管理-卸货完成")<button class="btn btn-sm btn-outline-success" @click="unloading(i,0)" v-if="info.cars[0].status==1">卸货完成</button>@endcan
-                                <div v-if="info.cars[0].status==2">@{{ info.cars[0].delivery_time }}</div>
-                            </div>
-                        </div>
-                        <div class="up" :id="'item-'+info.id" v-show="info.cars.length>1">
-                            <div class="row" v-for="(car,j) in info.cars" v-if="j!==0">
-                                <div class="col-2 font-weight-bold">@{{ car.appointment_number }}</div>
-                                <div class="col-2 text-secondary">@{{ car.license_plate_number }}</div>
-                                <div class="col-2 text-secondary">@{{ car.car ? car.car.name : '' }}</div>
-                                <div class="col-1 text-secondary">@{{ car.driver_name }}</div>
-                                <div class="col-2 text-secondary">@{{ car.driver_phone }}</div>
-                                <div class="col-3">
-                                    @can("入库管理-入库预约-预约管理-卸货完成")<button class="btn btn-sm btn-outline-success" @click="unloading(i,j)" v-if="car.status==1">卸货完成</button>@endcan
-                                    <div v-if="car.status==2">@{{ car.delivery_time }}</div>
-                                </div>
-                            </div>
-                        </div>
-                        <div class="text-center m-auto small cursor-pointer" v-if="info.cars.length>1" @click="upAll(info.id)">
-                            <span class="fa" :class="upList[info.id] ? 'fa-angle-double-down' : 'fa-angle-double-right'" style="margin-top: 2px;"></span>&nbsp;
-                            <span v-if="upList[info.id]">收起其余@{{ info.cars.length-1 }}条</span>
-                            <span v-else>展开其余@{{ info.cars.length-1 }}条</span>
-                        </div>
-                    </div>
-                </td>
-                <td>@{{ info.logistic ? info.logistic.name : '' }}</td>
-                <td>@{{ info.logistic_number }}</td>
-                <td><span v-html="warpText(info.procurement_number)"></span></td>
-                <td>
-                    <div v-if="info.details.length>0">
-                        <div class="row">
-                            <div class="col-5 font-weight-bold text-overflow-warp">@{{ info.details[0].commodity_id ? (info.details[0].commodity ? info.details[0].commodity.name : '') : info.details[0].name }}</div>
-                            <div class="col-4 text-secondary text-overflow-warp">@{{ info.details[0] | getCommodity }}</div>
-                            <div class="col-2 text-secondary">@{{ info.details[0].amount }}</div>
-                        </div>
-                        <div class="up" :id="'detail-'+info.id" v-show="info.details.length>1">
-                            <div class="row" v-for="(detail,i) in info.details" v-if="i!==0">
-                                <div class="col-5 font-weight-bold text-overflow-warp">@{{ detail.commodity_id ? (detail.commodity ? detail.commodity.name : '') : detail.name }}</div>
-                                <div class="col-4 text-secondary text-overflow-warp">@{{ detail | getCommodity }}</div>
-                                <div class="col-2 text-secondary">@{{ detail.amount }}</div>
-                            </div>
-                        </div>
-                        <div class="text-center m-auto small cursor-pointer" v-if="info.details.length>1" @click="upAllDetail(info.id)">
-                            <span class="fa" :class="upListDetail[info.id] ? 'fa-angle-double-down' : 'fa-angle-double-right'" style="margin-top: 2px;"></span>&nbsp;
-                            <span v-if="upListDetail[info.id]">收起其余@{{ info.details.length-1 }}条</span>
-                            <span v-else>展开其余@{{ info.details.length-1 }}条</span>
-                        </div>
-                    </div>
-                </td>-->
             </tr>
             <tr v-if="currentIndex!==undefined" id="await">
                 <td colspan="2"></td>
@@ -284,14 +177,6 @@
                 let dd = now.getDate();
                 this.today = yy+'-'+(mm<10 ? '0'+mm : mm)+'-'+(dd<10 ? '0'+dd : dd);
             },
-            /*watch:{
-                checkData:{
-                    handler(){
-                        document.querySelector('#all').checked = this.checkData.length === this.list.length;
-                    },
-                    deep:true
-                },
-            },*/
             methods: {
                 openDetails(index,isClose = false){
                     if (isClose){
@@ -403,8 +288,7 @@
                         window.tempTip.postBasicRequest("{{url('store/deliveryAppointment/unloading')}}",{id:this.list[i].cars[j].id},res=>{
                             this.list[i].cars[j].status = 2;
                             if (this.list[i].cars.every(car=>{
-                                if (car.status!=2)return false;
-                                return true
+                                return car.status==2
                             }))this.list[i].status = res;
                             return "成功确认";
                         })
@@ -426,14 +310,6 @@
                         })
                     })
                 },
-                /*checkAll(e){
-                    if (e.target.checked){
-                        this.checkData = [];
-                        this.list.forEach((el)=>{
-                            this.checkData.push(el.id);
-                        });
-                    }else this.checkData = [];
-                },*/
                 executeExport(isAll){
                     let url = '{{url('store/deliveryAppointment/export')}}';
                     let token='{{ csrf_token() }}';

+ 0 - 1
resources/views/store/handInStorage/receiveDetailPage.blade.php

@@ -295,7 +295,6 @@
                             if (res.data.success){
                                 this.asnDetails=res.data.data;
                                 this.$forceUpdate()
-                                return;
                             }else {
                                 window.tempTip.setDuration(3000);
                                 window.tempTip.show(res.data.data);

+ 2 - 2
resources/views/store/inStorage/storeItem.blade.php

@@ -10,12 +10,12 @@
                         <input class="checkItem" type="checkbox" :value="storeItem.id">
                     </td>
                     <td><span>@{{ i+1  }}</span></td>
-                    <td><span>@{{storeItem.store_asn_code}}</span></td>
+                    <td><span>@{{storeItem.store ? storeItem.store.asn_code : ''}}</span></td>
                     <td><span>@{{storeItem.asn_line_code}}</span></td>
                     <td class="text-muted"><span>@{{storeItem.name}}</span></td>
                     <td class="text-muted"><span>@{{storeItem.sku}}</span></td>
                     <td class="text-muted"><span>@{{storeItem.barcode}}</span></td>
-                    <td><span>@{{storeItem.depository_name}}</span></td>
+                    <td><span>@{{  storeItem.depository ? storeItem.depository.name : ''}}</span></td>
                     <td class="text-muted"><span>@{{storeItem.amount}}</span></td>
                     <td class="text-muted"><span>@{{storeItem.quality}}</span></td>
                     <td class="text-muted"><span>@{{storeItem.status}}</span></td>

+ 47 - 55
resources/views/transport/waybill/delivering.blade.php

@@ -9,10 +9,12 @@
                 <div class="text-center" :class="slideStatus[date] ? 'col-8' : 'col-12'" @click="selectedHeader(date)" @touchstart="startSlide()" @touchend="endSlide(date)">
                     @{{ date }}<i class="fa mr-2 pull-right" style="top: 2em" :class="header[date] ? 'fa-angle-down' : 'fa-angle-right'"></i>
                 </div>
-                <div class="col-4 bg-white p-1" :class="slideStatus[date] ? '' : 'd-none'">
-
+                <div class="col-4  p-0" :class="slideStatus[date] ? '' : 'd-none'">
                    <span class="btn btn-sm btn-success w-100" v-if="!item.pick_up_fee_total"  @click="dailyBillingApp(date)">按日输入专线费</span>
-                   <span class="text-info w-100 small" v-else>已输入专线费:<span class="font-weight-bold">@{{ item.pick_up_fee_total }}</span></span>
+                   <span class="text-info w-100 small" v-else>专线费:
+                       <span class="font-weight-bold">@{{ item.pick_up_fee_total }}</span>
+                       <span class="btn btn-sm btn-info text-white" @click="dailyBillingApp(date)">修改</span>
+                   </span>
                 </div>
             </div>
             <div class="card-body p-0" v-if="header[date]">
@@ -36,26 +38,35 @@
                         <div style="transform:scale(0.9);color:#02346a" class="pl-0 form-inline">
                             <div class="mr-3 text-nowrap form-inline">
                                 <label :for="'carrier_bill'+waybill.id">专线运单号:</label>
-                                <input :id="'carrier_bill'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].carrier_bill?'is-invalid tooltipTargetError':''"
-                                       v-if="waybill.isBtn || updatePool[waybill.id]" type="text" :value="waybill.carrier_bill"
+                                <input :id="'carrier_bill'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].carrier_bill?'is-invalid':''"
+                                       v-if="waybill.isBtn || updatePool[waybill.id]" type="text" v-model="waybill.carrier_bill"
                                         class="form-control form-control-sm " @click="enlarge($event)"  style="width: 50px">
                                 <span v-else  class="text-muted">@{{ waybill.carrier_bill }}</span>
                             </div>
                             <div class="mr-3 text-nowrap form-inline">
                                 <label :for="'inquire_tel'+waybill.id">查&nbsp;件&nbsp;电&nbsp;&nbsp;话:</label>
-                                <input :id="'inquire_tel'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].inquire_tel?'is-invalid tooltipTargetError':''"
-                                       v-if="waybill.isBtn || updatePool[waybill.id]" :value="waybill.inquire_tel"  @click="enlarge($event)"
+                                <input :id="'inquire_tel'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].inquire_tel?'is-invalid':''"
+                                       v-if="waybill.isBtn || updatePool[waybill.id]" v-model="waybill.inquire_tel"  @click="enlarge($event)"
                                        class="form-control form-control-sm" type="text" style="width:50px">
                                 <span v-else  class="text-muted">@{{ waybill.inquire_tel }}</span>
                             </div>
                             <div class="mr-3 text-nowrap form-inline">
                                 <label :for="'amount'+waybill.id">数量:</label>
                                 <div class="input-group input-group-sm" v-if="waybill.isBtn || updatePool[waybill.id]">
-                                    <input :id="'amount'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].amount?'is-invalid tooltipTargetError':''"
-                                     :value="waybill.amount" @click="enlarge($event)"
+                                    <input :id="'amount'+waybill.id" :class="errors['_'+waybill.id]&&(errors['_'+waybill.id].amount || errors['_'+waybill.id].amount_unit_name)?'is-invalid':''"
+                                           v-model="waybill.amount" @click="enlarge($event)"
                                    class="form-control" type="text" style="width:50px">
                                     <span class="input-group-append">
-                                        <span class="input-group-text">件</span>
+                                        <span class="input-group-text">
+                                            <span class="custom-control custom-radio">
+                                                <input :name="'radio-'+waybill.id" type="radio" class="custom-control-input" :id="'radio-one'+waybill.id" v-model="waybill.amount_unit_name" value="件"/>
+                                                <label class="custom-control-label" :for="'radio-one'+waybill.id">件</label>
+                                            </span>
+                                            <span class="custom-control custom-radio">
+                                                <input :name="'radio-'+waybill.id" type="radio" class="custom-control-input" :id="'radio-two'+waybill.id" v-model="waybill.amount_unit_name" value="托"/>
+                                                <label class="custom-control-label" :for="'radio-two'+waybill.id">托</label>
+                                            </span>
+                                        </span>
                                     </span>
                                 </div>
                                 <span v-else class="text-muted"><span v-if="waybill.amount">@{{ waybill.amount }} @{{ waybill.amount_unit_name }}</span></span>
@@ -63,9 +74,9 @@
                             <div class="mr-3 text-nowrap form-inline">
                                 <label :for="'carrier_weight_other'+waybill.id">重量:</label>
                                 <div class="input-group input-group-sm" v-if="waybill.isBtn || updatePool[waybill.id]">
-                                <input :id="'carrier_weight_other'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].carrier_weight_other?'is-invalid tooltipTargetError':''"
-                                   :value="waybill.carrier_weight_other" @click="enlarge($event)"
-                                    type="text" class="form-control" style="width:50px">
+                                <input :id="'carrier_weight_other'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].carrier_weight_other?'is-invalid':''"
+                                       v-model="waybill.carrier_weight_other" @click="enlarge($event)"
+                                    type="number" step="0.01" min="0" class="form-control" style="width:50px">
                                 <span class="input-group-append">
                                   <span class="input-group-text">KG</span>
                                 </span>
@@ -75,9 +86,9 @@
                             <div class="mr-3 text-nowrap form-inline">
                                 <label :for="'carrier_weight'+waybill.id">体积:</label>
                                 <div class="input-group input-group-sm" v-if="waybill.isBtn || updatePool[waybill.id]">
-                                    <input :id="'carrier_weight'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].carrier_weight?'is-invalid tooltipTargetError':''"
-                                           :value="waybill.carrier_weight" @click="enlarge($event)"
-                                           type="text" class="form-control" style="width:50px">
+                                    <input :id="'carrier_weight'+waybill.id" :class="errors['_'+waybill.id]&&errors['_'+waybill.id].carrier_weight?'is-invalid':''"
+                                           v-model="waybill.carrier_weight" @click="enlarge($event)"
+                                           type="number" step="0.01" min="0" class="form-control" style="width:50px">
                                     <span class="input-group-append">
                                       <span class="input-group-text">M³</span>
                                     </span>
@@ -89,13 +100,10 @@
                                 <div class="input-group input-group-sm">
                                     <input :id="'subjoin_fee'+waybill.id" :value="waybill.subjoin_fee"
                                            class="form-control" style="width:150px">
-<!--                                    <span class="input-group-append">
-                                      <span class="input-group-text">元</span>
-                                    </span>-->
                                 </div>
                             </div>
                             <span class="mr-3 text-nowrap">
-                                <button class="btn btn-sm btn-outline-success" @click="submit(date,waybill.isBtn,waybill.id)">提交</button>
+                                <button class="btn btn-sm btn-outline-success" type="button" @click="submit(date,waybill)">提交</button>
                                 <button v-if="!waybill.isBtn && !updatePool[waybill.id]" class="btn btn-sm btn-outline-info" @click="$set(updatePool,waybill.id,true);">修改</button>
                             </span>
                         </div>
@@ -139,7 +147,6 @@
             slideStatus:{},
             dailyBilling:{screenDate:'', billing:''},
             error:{screenDate:'', billing:''},
-            // dailyReady:{},
         },
         mounted:function(){
             $(".tooltipTarget").tooltip({'trigger':'hover'});
@@ -166,7 +173,7 @@
                 setTimeout(()=>{
                     element.classList.remove('translationRtoL');
                     this.$set(this.slideStatus,date,true);
-                },400);
+                },300);
             },
             lToR(date,element){
                 if (!this.slideStatus[date])return;
@@ -174,7 +181,7 @@
                 setTimeout(()=>{
                     element.classList.remove('translationLtoR');
                     this.$set(this.slideStatus,date,false);
-                },400);
+                },300);
             },
             selectedHeader(date){
                 if (this.header[date]===undefined)this.loadData(date);
@@ -214,6 +221,7 @@
                             carrier_weight_other:waybill.carrier_weight_other,
                             status:waybill.status,
                             amount:waybill.amount,
+                            amount_unit_name:waybill.amount_unit ? waybill.amount_unit.name : '',
                             inquire_tel:waybill.inquire_tel,
                             carrier_name:waybill.logistic ? waybill.logistic.name : '',
                             isBtn:!!!waybill.carrier_bill,
@@ -264,23 +272,18 @@
                     return !this.updatePool[waybillId] ? "附加费添加成功" : '';
                 });
             },
-            submit(date,isBtn,waybillId,id=null){
-                if(!isBtn){this.appendSubjoinFee(date,waybillId);if (!this.updatePool[waybillId])return;}
+            submit(date,waybill){
+                if(!waybill.isBtn){this.appendSubjoinFee(date,waybill.id);if (!this.updatePool[waybill.id])return;}
                 window.tempTip.confirm("确定要提交调配信息吗?",()=>{
                     let data={
-                        id           :  id ? id : waybillId,
-                        carrier_bill :  $("#carrier_bill"+waybillId).val(),
-                        inquire_tel  :  $("#inquire_tel"+waybillId).val(),
-                        amount  :  $("#amount"+waybillId).val(),
-                        carrier_weight  :  $("#carrier_weight"+waybillId).val(),
-                        carrier_weight_other  :  $("#carrier_weight_other"+waybillId).val(),
+                        id           :  waybill.id,
+                        carrier_bill :  waybill.carrier_bill,
+                        inquire_tel  :  waybill.inquire_tel,
+                        amount       :  waybill.amount,
+                        carrier_weight  :  waybill.carrier_weight,
+                        carrier_weight_other  :  waybill.carrier_weight_other,
+                        amount_unit_name : waybill.amount_unit_name
                     };
-                    if (!data["id"]){
-                        window.tempTip.setDuration(3000);
-                        window.tempTip.show("参数异常");
-                        return;
-                    }
-                    this.errors["_"+data['id']]={};
                     axios.post("{{url('transport/waybill/storeCarrierBill')}}",data)
                         .then(response=>{
                             if (response.data.error){
@@ -289,27 +292,16 @@
                                 return;
                             }
                             if (response.data.errors){
-                                this.$set(this.errors,"_"+data['id'],response.data.errors);
-                                setTimeout(function(){
-                                    $(".tooltipTargetError").tooltip('show');
-                                },1);
+                                let key = "_"+data['id']
+                                let errors = {};
+                                errors[key] = response.data.errors;
+                                this.errors = errors;
                                 return;
                             }
-                            this.groups[date].waybills.some(function (waybill) {
-                                if (waybill.id===data['id']){
-                                    waybill.carrier_bill=response.data.carrier_bill;
-                                    waybill.inquire_tel=response.data.inquire_tel;
-                                    waybill.amount=response.data.amount;
-                                    waybill.amount_unit_name=response.data.amount_unit_name;
-                                    waybill.carrier_weight=response.data.carrier_weight;
-                                    waybill.carrier_weight_other=response.data.carrier_weight_other;
-                                    if (waybill.carrier_bill)waybill.isBtn=false;
-                                    return true;
-                                }
-                            });
+                            waybill.isBtn=false;
                             tempTip.setDuration(2000);
-                            if (this.updatePool[waybillId]){
-                                tempTip.showSuccess('修改成功!');this.$set(this.updatePool,waybillId,false);
+                            if (this.updatePool[waybill.id]){
+                                tempTip.showSuccess('修改成功!');this.$set(this.updatePool,waybill.id,false);
                             }else tempTip.showSuccess('录入成功!');
                         }).catch(function (err) {
                             tempTip.setDuration(3000);

+ 41 - 37
resources/views/transport/waybill/index.blade.php

@@ -24,46 +24,49 @@
                     </ul>
                 </div>
             </div>
+
             <div id="form_div"></div>
-            <span class="dropdown">
-                <button class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget"
-                        data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">
-                    导出Excel
-                </button>
-                <div class="dropdown-menu" style="z-index: 1099">
-                    <a class="dropdown-item" @click="waybillExport(false)" href="javascript:">导出勾选内容</a>
-                    <a class="dropdown-item" @click="waybillExport(true)" href="javascript:">导出所有页</a>
+            <div class="ml-3 form-inline" id="btn">
+                <span class="dropdown">
+                    <button class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget"
+                            data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">
+                        导出Excel
+                    </button>
+                    <div class="dropdown-menu" style="z-index: 1099">
+                        <a class="dropdown-item" @click="waybillExport(false)" href="javascript:">导出勾选内容</a>
+                        <a class="dropdown-item" @click="waybillExport(true)" href="javascript:">导出所有页</a>
+                    </div>
+                </span>
+                <div class="form-check d-inline-block">
+                    <label class="form-check-label">
+                        <input type="checkbox" class="form-check-input" v-model="appendFluxInfo">导出附加FLUX信息
+                    </label>
                 </div>
-            </span>
-            <div class="form-check d-inline-block">
-                <label class="form-check-label">
-                    <input type="checkbox" class="form-check-input" v-model="appendFluxInfo">导出附加FLUX信息
-                </label>
-            </div>
-            @can('运输管理-运单-图片上传')<button class="btn btn-sm btn-outline-info" data-target="#batchUploadImg" data-toggle="modal">批量上传图片</button>@endcan
-            @can('运输管理-运单-图片删除')<button class="btn btn-sm btn-outline-danger" @click="deleteImg()">批量删除图片</button>@endcan
-            @if($uriType=='' || $uriType=='专线')
-                @can('运输管理-运单-按日计算专线费')
-                    <button class="btn btn-sm btn-outline-success tooltipTarget" data-target="#dailyBilling" data-toggle="modal"
-                            title="计算指定日期下的所有专线费,不考虑有无货主权限">按日输入专线费</button>@endcan
-            @endif
-            @can('运输管理-编辑')<button class="btn btn-sm btn-outline-info tooltipTarget"
-                        title="合并多条运单至一条,已填写信息将被累加处理" @click="waybillMerge()">运单合并</button>
-            <button class="btn btn-sm btn-outline-info tooltipTarget"
-                    title="将已合并运单拆分返回原状态" @click="waybillSplit()">拆单返回</button>
-            @endcan
-            @if($uriType=='' || $uriType=='德邦物流')
+                @can('运输管理-运单-图片上传')<button class="btn btn-sm btn-outline-info" data-target="#batchUploadImg" data-toggle="modal">批量上传图片</button>@endcan
+                @can('运输管理-运单-图片删除')<button class="btn btn-sm btn-outline-danger" @click="deleteImg()">批量删除图片</button>@endcan
+                @if($uriType=='' || $uriType=='专线')
+                    @can('运输管理-运单-按日计算专线费')
+                        <button class="btn btn-sm btn-outline-success tooltipTarget" data-target="#dailyBilling" data-toggle="modal"
+                                title="计算指定日期下的所有专线费,不考虑有无货主权限">按日输入专线费</button>@endcan
+                @endif
+                @can('运输管理-编辑')<button class="btn btn-sm btn-outline-info tooltipTarget"
+                                       title="合并多条运单至一条,已填写信息将被累加处理" @click="waybillMerge()">运单合并</button>
                 <button class="btn btn-sm btn-outline-info tooltipTarget"
-                        title="打印快递面单" @click="expressFaceList()">打印快递面单</button>
-            @endif
-            <div>
-                @if(Session::has('successTip'))
-                    <div class="alert alert-success h1">{{Session::get('successTip')}}</div>
+                        title="将已合并运单拆分返回原状态" @click="waybillSplit()">拆单返回</button>
+                @endcan
+                @if($uriType=='' || $uriType=='德邦物流')
+                    <button class="btn btn-sm btn-outline-info tooltipTarget"
+                            title="打印快递面单" @click="expressFaceList()">打印快递面单</button>
                 @endif
+                <div>
+                    @if(Session::has('successTip'))
+                        <div class="alert alert-success h1">{{Session::get('successTip')}}</div>
+                    @endif
+                </div>
+                {{--    德邦面单--}}
+                <div id="lodopTips"></div>
+                {{--    德邦面单--}}
             </div>
-            {{--    德邦面单--}}
-            <div id="lodopTips"></div>
-            {{--    德邦面单--}}
 
             <table class="table table-striped table-bordered table-hover text-nowrap waybill-table td-min-width-80" style="background: #fff;" id="table">
                 <tr v-for="(waybill,i) in waybills" :class="[waybill.status=='待重审'?'td-red':''||waybill.status=='已完结'?'td-green':'',selectTr==waybill.id ? 'tr-select' : '']"
@@ -686,6 +689,7 @@
                     el:"#form_div",
                     condition:data,
                     param:param,
+                    appendDom : "btn",
                 });
                 this.form.init();
                 this.rendingHeader();
@@ -889,7 +893,7 @@
                         column: column,
                         data: this.waybills,
                         restorationColumn: 'id',
-                        fixedTop:($('#form_div').height())+2,
+                        fixedTop:($('#form_div').height()) + ($('#btn').height())+2,
                         before : [
                             {colspan:'4',value: '', class:"table-header-layer-1"},
                             {colspan:'15',value: '运单信息',font:"fa fa-file-text-o", class:"table-header-layer-1"},
@@ -1434,7 +1438,7 @@
                     });
                     return val;
                 },
-            }
+            },
         });
         // modal 隐藏时修改 input 为空
         $("#exampleModal").on('hide.bs.modal',function(e){

+ 1 - 0
routes/apiLocal.php

@@ -267,6 +267,7 @@ Route::prefix('workOrder')->group(function(){
     Route::post('buildOrderIssue','WorkOrderController@buildOrderIssueApi')->name('workOrder.buildOrderIssueApi');  // 生成问题件
     Route::post('updateIssueType','WorkOrderController@updateIssueTypeApi')->name('workOrder.updateIssueTypeApi'); // 修改问题类型
     Route::post('batchUpdateIssueType','WorkOrderController@batchUpdateIssueTypeApi')->name('workOrder.batchUpdateIssueTypeApi'); // 修改问题类型
+    Route::delete('/{id}','WorkOrderController@destroyApi')->name('workOrder.destroyApi');
  });
 /*出库*/
 Route::group(['prefix'=>'storeOut'],function(){

+ 1 - 0
routes/web.php

@@ -795,6 +795,7 @@ Route::group(['prefix'=>'package'],function(){
         Route::post('thaw','OrderController@thaw');
         Route::post('deAllocation','OrderController@deAllocation');
         Route::post('deAllocationAll','OrderController@deAllocationAll');
+        Route::post('manualBack','OrderController@manualBack');
         Route::post('resetLogisticsGetMark','OrderController@resetLogisticsGetMark');
         Route::post('resetInterfaceReturnMark','OrderController@resetInterfaceReturnMark');
         Route::post('createRejectedBill','OrderController@createRejectedBill');

+ 1 - 1
tests/Feature/LogisticZopSyncTest.php

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

+ 207 - 0
tests/Services/LogisticSFService/SetExceptionStatusTest.php

@@ -0,0 +1,207 @@
+<?php
+
+
+namespace Tests\Services\LogisticSFService;
+
+
+use App\OrderPackage;
+use App\Services\LogisticSFService;
+use Tests\TestCase;
+
+class SetExceptionStatusTest extends TestCase
+{
+    /**
+     * @var LogisticSFService $service
+     */
+    private $service;
+
+    protected function setUp(): void
+    {
+        parent::setUp(); // TODO: Change the autogenerated stub
+        $this->service = app('LogisticSFService');
+
+    }
+
+    public function test_单号异常()
+    {
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263_1')->delete();
+        $data = [
+            "logistic_number" => "SF1332897469263_1",
+            "status" => "已签收",
+            "received_at" => "2021-09-09 12:11:03",
+            "transfer_status" => [
+                ["accept_time" => "2021-09-08 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => "2021-09-08 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => "2021-09-08 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => "2021-09-08 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+            ],
+        ];
+        factory(OrderPackage::class)->create([
+            'status' => "生成订单",
+            'exception_status' => "单号异常",
+            'logistic_number' => 'SF1332897469263_1',
+        ]);
+        $response = $this->service->setExceptionStatus($data);
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263_1')->delete();
+        $this->assertEquals($data, $response);
+    }
+
+    public function test_延迟发货_16()
+    {
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $data = [
+            "logistic_number" => "SF1332897469263",
+            "status" => "已签收",
+            "received_at" => "2021-09-09 12:11:03",
+            "transfer_status" => [],
+        ];
+        factory(OrderPackage::class)->create([
+            'status' => "生成订单",
+            'logistic_number' => 'SF1332897469263',
+            'transfer_status' => null,
+            'sent_at' => null,
+            'created_at' => now()->subDays(3),
+        ]);
+        $response = $this->service->setExceptionStatus($data);
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $this->assertEquals('延迟发货', $response['exception_status']);
+    }
+
+    public function test_疑似库内丢件()
+    {
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $data = [
+            "logistic_number" => "SF1332897469263",
+            "status" => "已签收",
+            "received_at" => "2021-09-09 12:11:03",
+            "transfer_status" => [],
+        ];
+        factory(OrderPackage::class)->create([
+            'status' => "生成订单",
+            'logistic_number' => 'SF1332897469263',
+            'transfer_status' => null,
+            'sent_at' => now()->subDays(3),
+            'created_at' => now()->subDays(3),
+            'weighed_at' => null,
+        ]);
+        $response = $this->service->setExceptionStatus($data);
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $this->assertEquals('疑似库内丢件', $response['exception_status']);
+    }
+
+    public function test_揽件异常()
+    {
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $data = [
+            "logistic_number" => "SF1332897469263",
+            "status" => "已签收",
+            "received_at" => "2021-09-09 12:11:03",
+            "transfer_status" => [],
+        ];
+        factory(OrderPackage::class)->create([
+            'status' => "生成订单",
+            'logistic_number' => 'SF1332897469263',
+            'transfer_status' => null,
+            'sent_at' => now()->subDays(3),
+            'created_at' => now()->subDays(3),
+            'weighed_at' => now()->subDays(2),
+        ]);
+        $response = $this->service->setExceptionStatus($data);
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $this->assertEquals('揽件异常', $response['exception_status']);
+    }
+
+    public function test_在途异常大于3上海()
+    {
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $data = [
+            "logistic_number" => "SF1332897469263",
+            "status" => "在途",
+            "received_at" => null,
+            "transfer_status" => [
+                ["accept_time" => "2021-09-06 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => "2021-09-07 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => "2021-09-08 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => now()->subHours(25)->toDateTimeString(), "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                //最近一条是在24h前
+            ],
+        ];
+        $order =  factory(\App\Order::class)->create([
+            'province' =>'上海'
+        ]);
+        factory(OrderPackage::class)->create([
+            'status' => "生成订单",
+            'logistic_number' => 'SF1332897469263',
+            'transfer_status' => OrderPackage::switchStatus('在途'),
+            'sent_at' => now()->subDays(3),
+            'created_at' => now()->subDays(3),
+            'weighed_at' => now()->subDays(2),
+            'order_id' =>$order->id,
+        ]);
+        $response = $this->service->setExceptionStatus($data);
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $this->assertEquals('在途异常', $response['exception_status']);
+    }
+    public function test_在途异常小于3上海()
+    {
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $data = [
+            "logistic_number" => "SF1332897469263",
+            "status" => "在途",
+            "received_at" => null,
+            "transfer_status" => [
+                ["accept_time" => "2021-09-08 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => now()->subHours(25)->toDateTimeString(), "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                //最近一条是在24h前
+            ],
+        ];
+        $order =  factory(\App\Order::class)->create([
+            'province' =>'上海'
+        ]);
+        factory(OrderPackage::class)->create([
+            'status' => "生成订单",
+            'logistic_number' => 'SF1332897469263',
+            'transfer_status' => OrderPackage::switchStatus('在途'),
+            'sent_at' => now()->subDays(3),
+            'created_at' => now()->subDays(3),
+            'weighed_at' => now()->subDays(2),
+            'order_id' =>$order->id,
+        ]);
+        $response = $this->service->setExceptionStatus($data);
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $this->assertEquals('在途异常', $response['exception_status']);
+    }
+    public function test_在途异常大于3黑龙江()
+    {
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $data = [
+            "logistic_number" => "SF1332897469263",
+            "status" => "在途",
+            "received_at" => null,
+            "transfer_status" => [
+                ["accept_time" => "2021-08-06 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => "2021-08-07 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => "2021-08-08 19:25:42", "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                ["accept_time" => now()->subHours(73)->toDateTimeString(), "accept_address" => "上海市", "remark" => "顺丰速运 已收取快件",],
+                //最近一条是在24h前
+            ],
+        ];
+        $order =  factory(\App\Order::class)->create([
+            'province' =>'黑龙江省'
+        ]);
+        factory(OrderPackage::class)->create([
+            'status' => OrderPackage::switchStatus('在途'),
+            'logistic_number' => 'SF1332897469263',
+            'transfer_status' => [],
+            'sent_at' => now()->subDays(3),
+            'created_at' => now()->subDays(3),
+            'weighed_at' => now()->subDays(2),
+            'order_id' =>$order->id,
+        ]);
+        $response = $this->service->setExceptionStatus($data);
+        OrderPackage::query()->where('logistic_number', 'SF1332897469263')->delete();
+        $this->assertEquals('在途异常', $response['exception_status']);
+    }
+
+
+}

+ 28 - 0
tests/Services/LogisticYTSync/SyncTest.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace Tests\Services\LogisticYTSync;
+
+use App\Jobs\LogisticYTOSync;
+use App\Services\LogisticYTOService;
+use Tests\TestCase;
+
+class SyncTest extends TestCase
+{
+
+    /** @var LogisticYTOService $service */
+    public $service;
+
+    function setUp(): void
+    {
+        parent::setUp();
+        $this->service = app('LogisticYTOService');
+    }
+
+    /**
+     * @test
+     */
+    public function format_test()
+    {
+        LogisticYTOSync::dispatch('YT5781193551713');
+    }
+}