Просмотр исходного кода

Merge branch 'master' into Haozi

# Conflicts:
#	app/Http/Controllers/TestController.php
haozi 4 лет назад
Родитель
Сommit
19aadf4e6c
26 измененных файлов с 558 добавлено и 347 удалено
  1. 9 1
      app/Authority.php
  2. 1 1
      app/Console/Commands/AccordingToOwnersManualBack.php
  3. 2 5
      app/Http/Controllers/CustomerController.php
  4. 2 2
      app/Http/Controllers/OrderController.php
  5. 1 1
      app/Http/Controllers/OwnerController.php
  6. 10 5
      app/Http/Controllers/PackageLogisticController.php
  7. 13 5
      app/Http/Controllers/ProcessController.php
  8. 2 2
      app/Http/Controllers/StorageController.php
  9. 78 32
      app/Http/Controllers/TestController.php
  10. 0 44
      app/Jobs/OrderPackageReceivedSync.php
  11. 100 118
      app/Jobs/ResetInstantBill.php
  12. 0 1
      app/Notifications/RoutineNotification.php
  13. 9 9
      app/OwnerFeeExpress.php
  14. 15 0
      app/OwnerLogisticFeeReport.php
  15. 20 71
      app/Services/OrderPackageReceivedSyncService.php
  16. 55 20
      app/Services/OrderPackageService.php
  17. 6 3
      app/Services/OrderService.php
  18. 1 0
      app/Services/RejectedBillService.php
  19. 86 20
      app/Traits/LogisticSyncTrait.php
  20. 1 1
      database/factories/OrderPackageFactory.php
  21. 34 0
      database/migrations/2021_09_23_170820_change_authorities_table_add_column_route.php
  22. 1 1
      resources/views/finance/_resetInstantBill.blade.php
  23. 2 1
      resources/views/finance/instantBill.blade.php
  24. 10 2
      resources/views/finance/settlementBills/expressFee/report/index.blade.php
  25. 9 2
      resources/views/layouts/notification.blade.php
  26. 91 0
      tests/Services/OrderPackageReceivedSyncService/TestSetExceptionStatus.php

+ 9 - 1
app/Authority.php

@@ -15,7 +15,15 @@ class Authority extends Model
     use ModelLogChanging;
     use SoftDeletes;
     use ModelTimeFormat;
-    protected $fillable = ['name','parent_id','alias_name','permission'];
+    protected $fillable = ['name','parent_id','alias_name','permission',"route","method"];
+
+    const METHOD = [
+        0 => "GET",
+        1 => "POST",
+        2 => "PUT",
+        3 => "DELETE",
+    ];
+
     function roles(){
         return $this->belongsToMany('App\Role','authority_role','id_authority','id_role');
     }

+ 1 - 1
app/Console/Commands/AccordingToOwnersManualBack.php

@@ -107,7 +107,7 @@ class AccordingToOwnersManualBack extends Command
         foreach ($orders as $order){
             if (!$order->soreference5) continue;
             if (!$conn)$conn = $this->getFluxConnection();
-            $res=$orderService->allocation($order->orderno,$order->warehouseid,$conn);
+            $res=$orderService->allocation($order->orderno,null,$order->warehouseid,$conn);
             if (mb_substr($res,0,3)=='000') array_push($allocationOrderNos,$order->orderno);
         }
         if ($conn)$this->releaseFluxConnection($conn);

+ 2 - 5
app/Http/Controllers/CustomerController.php

@@ -19,13 +19,11 @@ use App\Services\OwnerReportService;
 use App\Services\OwnerService;
 use App\Store;
 use App\UserWorkgroup;
-use Exception;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
-use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Validator;
 use Oursdreams\Export\Export;
 
@@ -515,7 +513,6 @@ class CustomerController extends Controller
 
     public function resetInstantBill()
     {
-        $this->error("功能废弃");
         ini_set('max_execution_time', 2500);
         $startData = request("startDate");
         $endDate = request("endDate");
@@ -527,8 +524,8 @@ class CustomerController extends Controller
         $details->get()->each(function ($detail){
             dispatch(new ResetInstantBill($detail));
         });
-        $this->restoreResetInstantBillOrder($startData,$endDate);
-        $this->restoreResetInstantBillStore($startData,$endDate);
+        //$this->restoreResetInstantBillOrder($startData,$endDate);
+        //$this->restoreResetInstantBillStore($startData,$endDate);
         $this->success();
     }
     private function restoreResetInstantBillOrder($startData,$endDate)

+ 2 - 2
app/Http/Controllers/OrderController.php

@@ -375,7 +375,7 @@ sql;
         $service=app("OrderService");
         foreach ($docOrders as $order){
             if ($order->sostatus=='00' || $order->sostatus=='10' || $order->sostatus=='20'){
-                $res = $service->allocation($order->orderno,$order->warehouseid);
+                $res = $service->allocation($order->orderno,null,$order->warehouseid);
                 if (mb_substr($res,0,3)!='000') {
                     array_push($failNo,$order->orderno);
                     app('LogService')->log(__METHOD__,'手动回传分配失败'.__FUNCTION__,json_encode($order->orderno),Auth::user()['id']);
@@ -413,7 +413,7 @@ sql;
                 continue;
             }
             if (!$conn)$conn = $this->getFluxConnection();
-            $res = $service->allocation($item["code"],$item["warehouse"],$conn);
+            $res = $service->allocation($item["code"],null,$item["warehouse"],$conn);
             if (mb_substr($res,0,3)=='000')continue;
             $error[] = "'{$item["code"]}'{$res}";
         }

+ 1 - 1
app/Http/Controllers/OwnerController.php

@@ -211,7 +211,7 @@ class OwnerController extends Controller
         $id = $request->input('id');
         $owner = Owner::query()->whereNotNull('deleted_at')->where('id', $id)->first();
         $owner->update(["deleted_at" => null]);
-        app("OwnerService")->createAuthority($owner);
+        //app("OwnerService")->createAuthority($owner);
         app('LogService')->log(__METHOD__, __FUNCTION__, json_encode($request->toArray()), Auth::user()['id']);
         return ['success' => 'true', 'owner' => $owner];
     }

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

@@ -77,11 +77,11 @@ class PackageLogisticController extends Controller
                 //标记为手动更新
                 'is_manual_update' => true,
             ];
-            if ($status==='已签收') {
+            if ($status === '已签收') {
                 $data['exception_status'] = 0;
             }
             OrderPackage::query()->whereIn('logistic_number', $request->input('logistic_numbers'))->update($data);
-        }else if (!empty($request->input('exceptionStatus'))) {
+        } else if (!empty($request->input('exceptionStatus'))) {
             OrderPackage::query()->whereIn('logistic_number', $request->input('logistic_numbers'))->update([
                 'exception_status' => OrderPackage::switchExceptionStatus($request->input('exceptionStatus')),
                 //标记为手动更新
@@ -96,6 +96,7 @@ class PackageLogisticController extends Controller
      */
     public function export(Request $request, OrderPackageFilters $filters)
     {
+        ini_set('max_execution_time', 300);
         /** @var UserService $userService */
         $userService = app('UserService');
         $owner_ids = $userService->getPermittingOwnerIds(auth()->user());
@@ -150,14 +151,14 @@ class PackageLogisticController extends Controller
             if (is_array($orderPackage->transfer_status) && !empty($orderPackage->transfer_status)) {
                 foreach ($orderPackage->transfer_status as $transfer) {
                     $transferItemStr = "";
-                    $transferItemStr = $transferItemStr . $transfer['accept_address'] . "   " . $transfer['remark'] . "   " . $transfer['accept_time'];
+                    $transferItemStr = $transferItemStr . $transfer['accept_address'] ?? '' . "   " . $transfer['remark'] ?? '' . "   " . $transfer['accept_time'] ?? '';
                     $transfer_status = $transfer_status . $transferItemStr . ",\r\n";
                 }
             }
             $remark = "";
             if (!empty($orderPackage->orderPackageRemarks)) {
                 foreach ($orderPackage->orderPackageRemarks as $remarkItem) {
-                    $remark = $remark . $remarkItem->content . '-' . $remarkItem->user->name . '-' . $remarkItem->created_at . ",\r\n";
+                    $remark = $remark . $remarkItem->content ?? '' . '-' . $remarkItem->user->name ?? '' . '-' . $remarkItem->created_at ?? '' . ",\r\n";
                 }
             }
             $logsContent = "";
@@ -166,7 +167,11 @@ class PackageLogisticController extends Controller
             if ($orderPackage->order && $orderPackage->order->issue) {
                 foreach ($orderPackage->order->issue->logs as $log) {
                     $logsContent = $logsContent . $log->content . ",\r\n";
-                    $users = $users . $log->user->name . ",\r\n";
+                    $name = '';
+                    if (!empty($log->user)) {
+                        $name = $log->user->name;
+                    }
+                    $users = $users . $name . ",\r\n";
                     $logCreatedAt = $logCreatedAt . $log->created_at . ",\r\n";
                 }
             }

+ 13 - 5
app/Http/Controllers/ProcessController.php

@@ -1065,11 +1065,19 @@ class ProcessController extends Controller
                     $query->where('code',$str)->orWhere('name',$str);
                 })->first();
                 if (!$owner){
-                    $owner = Owner::query()->create([
-                        'code' => $str,
-                        'name' => $str
-                    ]);
-                    app('LogService')->log(__METHOD__,"二次加工单录入导入商品数据时添加货主".__FUNCTION__,json_encode($owner),Auth::user()['id']);
+                    $owner=Owner::query()->whereNotNull("deleted_at")->where(function ($query)use($str){
+                        $query->where('code',$str)->orWhere('name',$str);
+                    })->first();
+                    if (!$owner){
+                        $owner = Owner::query()->create([
+                            'code' => $str,
+                            'name' => $str
+                        ]);
+                        Log::info("二次加工录入货主",["owner"=>$owner->toJson(),"user"=>Auth::id()]);
+                    }else{
+                        $owner->update(["deleted_at"=>null]);
+                        Log::info("二次加工恢复货主",["owner"=>$owner->toJson(),"user"=>Auth::id()]);
+                    }
                 }
             }
             $goods = Commodity::query()->with('barcodes')->where('owner_id',$owner->id)//->whereNull('owner_id')  保留,暂时不知为何限定货主为空

+ 2 - 2
app/Http/Controllers/StorageController.php

@@ -158,10 +158,10 @@ sql;
         //清理任务
         $data = '';
         //剔除准备执行任务但没有真正开始执行的待定库位
-        $occupy = Station::query()->select("id")->whereIn("code",$boxes)->where("status",1)->get();
+        $occupy = Station::query()->select("id","code")->whereIn("code",$boxes)->where("status",1)->get();
         foreach ($occupy as $item){
-            unset($boxes[array_search($item->code,$boxes)]);
             $data .= '“'.$item->code.'”,';
+            unset($boxes[array_search($item->code,$boxes)]);
         }
         if ($occupy->count()>0){
             $data .= "存在任务待处理,无法调取  ";

+ 78 - 32
app/Http/Controllers/TestController.php

@@ -7,6 +7,7 @@ use App\Batch;
 use App\Commodity;
 use App\CommodityMaterialBoxModel;
 use App\Components\AsyncResponse;
+use App\Components\Database;
 use App\Components\ErrorPush;
 use App\ErrorTemp;
 use App\Feature;
@@ -16,7 +17,7 @@ use App\Jobs\BatchTaskJob;
 use App\Jobs\CacheShelfTaskJob;
 use App\Jobs\OrderCreateInstantBill;
 use App\Jobs\OrderCreateWaybill;
-use App\Jobs\SettlementBillReportTask;
+use App\Jobs\SettlementBillReportJob;
 use App\Jobs\StoreCreateInstantBill;
 use App\Jobs\TestJob;
 use App\Jobs\WeightUpdateInstantBill;
@@ -29,6 +30,7 @@ use App\OracleDOCASNHeader;
 use App\OracleDOCOrderHeader;
 use App\OracleDocOrderPackingSummary;
 use App\Order;
+use App\OrderBin;
 use App\OrderIssue;
 use App\OrderIssueProcessLog;
 use App\OrderPackage;
@@ -103,7 +105,7 @@ use Symfony\Component\ErrorHandler\Error\FatalError;
 
 class TestController extends Controller
 {
-    use AsyncResponse, ErrorPush;
+    use AsyncResponse, ErrorPush, Database;
 
     const ASNREFERENCE_2 = 'ASNREFERENCE2';
 
@@ -120,42 +122,82 @@ class TestController extends Controller
             dd("方法不存在");
         }
     }
-    public function test1()
+    /**
+     * @param $wave
+     * @return string
+     */
+    private function wms_status($wave): string
     {
-        try {
-            $b = DB::connection("oracle")->select("SELECT * FROM DOC_ORDER_HEADER");
-            dump(count($b));
-        }catch (\Exception $e){
-            dd($e);
-        }catch (\Error $e1){
-            dd($e1);
+        switch ($wave->wavestatus) {
+            case 00:
+                $wms_status = '创建';
+                break;
+            case 40:
+                $wms_status = '部分收货';
+                break;
+            case 90:
+                $wms_status = '取消';
+                break;
+            case 99:
+                $wms_status = '完成';
+                break;
+            case 62:
+                $wms_status = '部分装箱';
+                break;
+            default:
+                $wms_status = (string)$wave->wavestatus;
         }
-        dd(round(memory_get_peak_usage() / 1024 / 1024, 2));
+        return $wms_status;
+    }
+    public function assignBatch()
+    {
+        $code = \request("code");
+        $batches = Batch::query()->where("code",$code)->get();
+        if (!$batches->count()){
+            $wave = DB::connection("oracle")->selectOne(DB::raw("select * from DOC_WAVE_HEADER where WAVENO = ?"),[$code]);
+            if (!$wave){
+                dd("FLUX无波次");
+            }
+            $owner = app("OwnerService")->codeGetOwner($wave->customerid);
+            $obj = [
+                "wms_status" => $this->wms_status($wave),
+                "wms_type"=>$wave->descr,
+                "created_at"=>date("Y-m-d H:i:s"),
+                "wms_created_at"=>$wave->addtime,
+                "updated_at"=>$wave->edittime,
+                "owner_id"=>$owner->id,
+            ];
+            $wave = Batch::query()->where("code",$code)->first();
+            if (!$wave){
+                $obj["code"] = $code;
+                $wave = Batch::query()->create($obj);
+            }else{
+                Batch::query()->where("code",$code)->update($obj);
+            }
+            $ordernos = array_column(DB::connection("oracle")->select(DB::raw("select orderno from DOC_WAVE_DETAILS where WAVENO = ?"),[$code]),"orderno");
+            Order::query()->whereIn("code",$ordernos)->update([
+                "batch_id"=>$wave->id
+            ]);
+            Order::query()->with(["batch","bin"])->whereIn("code",$ordernos)->get()->each(function ($order){
+                if (!$order->bin){
+                    $bin = DB::connection("oracle")->selectOne(DB::raw("select seqno from DOC_WAVE_DETAILS where waveno = ? and orderno = ?"),[$order->batch->code,$order->code]);
+                    if ($bin){
+                        OrderBin::query()->create([
+                            'order_id' => $order->id,
+                            'number' => $bin->seqno,
+                        ]);
+                    }
+                }
+            });
+            $batches = Batch::query()->where("code",$code)->get();
+        }
+        app("BatchService")->assignTasks($batches);
     }
 
     public function test()
     {
-        $b = [];
-        for ($i=0;$i<100000;$i++){
-            $b[] = $i;
-        }
-        dd(round(memory_get_peak_usage() / 1024 / 1024, 2));
-        $area = OwnerAreaReport::query()->find(398);
-        if (!$area->ownerStoragePriceModel)dd("error");
-        //信息提取模板
-        $GLOBALS["FEE_INFO"] = [
-            "area_id"           =>$area->id,
-            "counting_type"     =>$area->ownerStoragePriceModel->counting_type,
-            "using_type"        =>$area->ownerStoragePriceModel->using_type,
-            "fee_description"   =>"",
-            "total_fee"         =>0,
-            "tax_rate"          =>0,
-        ];
-        list($money,$taxFee) = app('OwnerStoragePriceModelService')
-            ->calculationAmount($area->ownerStoragePriceModel,$area->accounting_area,$area->owner_id,$area->counting_month);
-        dd($money,$taxFee);
-
-        dd(Notification::send(User::query()->where("name","zhouzhendong")->get(),new RoutineNotification(SeeLog::query()->first()->toArray())));
+        dd(Notification::send(User::query()->where("name","baoshi56")->get(),
+            new RoutineNotification(SeeLog::query()->first()->toArray())));
         $user = Auth::user();
         $remark = "zengjunlj";
         $ownerName = 'zengjunlj' ?? '';
@@ -583,4 +625,8 @@ sql;
 //        $this->setOrderManualBackAt();//回传结束时间标记
 
     }
+    public function init_SettlementBillReportTask()
+    {
+        $this->dispatch(new SettlementBillReportJob('2021-08-01',[]));
+    }
 }

+ 0 - 44
app/Jobs/OrderPackageReceivedSync.php

@@ -1,44 +0,0 @@
-<?php
-
-namespace App\Jobs;
-
-use App\Services\OrderPackageReceivedSyncService;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Foundation\Bus\Dispatchable;
-use Illuminate\Queue\InteractsWithQueue;
-use Illuminate\Queue\SerializesModels;
-
-/**
- * 同步快递路由信息任务 调用时需要延迟1h触发
- * Class OrderPackageReceivedSync
- * @package App\Jobs
- */
-class OrderPackageReceivedSync implements ShouldQueue
-{
-    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
-
-    protected $logisticNumbers;
-    protected $service;
-
-    /**
-     * OrderPackageReceivedSync constructor.
-     * @param $logisticNumbers
-     */
-    public function __construct($logisticNumbers)
-    {
-        $this->logisticNumbers = $logisticNumbers;
-        $this->service =  new OrderPackageReceivedSyncService();
-    }
-
-
-    /**
-     * Execute the job.
-     * @return void
-     * @throws \Exception
-     */
-    public function handle()
-    {
-        $this->service->syncLogisticRouteApi($this->logisticNumbers);
-    }
-}

+ 100 - 118
app/Jobs/ResetInstantBill.php

@@ -6,6 +6,7 @@ use App\Feature;
 use App\Order;
 use App\OwnerFeeDetail;
 use App\OwnerFeeDetailLogistic;
+use App\OwnerFeeExpress;
 use App\Process;
 use App\Province;
 use App\RejectedBill;
@@ -49,176 +50,157 @@ class ResetInstantBill implements ShouldQueue
      */
     public function handle()
     {
-        /*switch ($this->detail->outer_table_name){
+        switch ($this->detail->outer_table_name){
             case "orders":
-                //检查订单对象
                 $order = Order::query()->find($this->detail->outer_id);
-                if (!$order || $order->wms_status != "订单完成")break;
+                if (!$order)break;
+                //加载所需数据
                 $order->loadMissing(["logistic","shop","packages.commodities.commodity","batch"]);
-                $service = app("OwnerPriceExpressService");
-                $logistic_fee = 0;
-                $amount = 0;
-                $volume = 0;
-                $weight = 0;
-                $logistic_bill = "";
-
-                if (!$order->logistic || $order->logistic->type == "物流")$logistic_fee = null;
-
-                $items = [];
-                $isBunched = $order->logistic && $order->logistic->is_bunched=='Y';
-                $weightExceptionMark = false;
-                $provinceId = null;
-                $logisticTaxFee = 0;
-                foreach ($order->packages as &$package){
-                    $tax = 0;
-
-                    $logistic_bill .= $package->logistic_number.",";
-                    $volume += $package->bulk;
-                    $weight += $package->weight;
-                    if (!$weightExceptionMark && (!$package->weight || $package->weight<0))$weightExceptionMark = true;
-                    $partAmount = 0;
-                    foreach($package->commodities as $commodity){
-                        $partAmount += $commodity->amount;
-                    }
-                    $amount += $partAmount;
-
-                    $provinceName = mb_substr($order->province,0,2);
-                    $province = app(CacheService::class)->getOrExecute("province_".$provinceName,function ()use($provinceName){
-                        return Province::query()->where("name","like",$provinceName."%")->first();
-                    },86400);
-                    $fee = null;
-                    if ($province){
-                        if (!$provinceId)$provinceId = $province->id;
-                        else if ($provinceId!=$province->id)$weightExceptionMark = true;
-                        if (!$isBunched)list($fee,$tax) = $service->matching($package->weight, $order->owner_id, $order->logistic_id, $province->id);
-                    }else $logistic_fee = null;
-
-                    $items[] = [
-                        "amount" => $partAmount,
-                        "logistic_bill" => $package->logistic_number,
-                        "volume"=>$package->bulk,
-                        "weight"=>$package->weight,
-                        "logistic_fee" => $fee,
-                        "tax_fee" => $tax,
-                    ];
-                    if ($logistic_fee!==null){
-                        if (!$fee || $fee<0)$logistic_fee = null;
-                        else $logistic_fee += $fee;
-                    }
-                    $logisticTaxFee += $tax;
-                }
-                if ($isBunched && !$weightExceptionMark && $weight>0 && $provinceId)list($logistic_fee,$logisticTaxFee) = $service->matching($weight, $order->owner_id, $order->logistic_id, $provinceId);
-                if ($logistic_fee!==null && $logistic_fee<0)$logistic_fee = null;
-
+                //获取运输费
+                $logisticInfo = app("OrderService")->getLogisticFeeInfo($order);
+                //获取作业费
+                /** @var OwnerPriceOperationService $service */
                 $service = app("OwnerPriceOperationService");
-                list($id,$money,$workTaxFee) = $service->matching($order,Feature::MAPPING["order"],$order->owner_id,"出库");
-
-                $this->detail->update([
-                    "owner_id"          => $order->owner_id,
-                    "worked_at"         => $order->wms_edittime ?? $order->updated_at,
-                    "shop_id"           => $order->shop_id,
-                    "operation_bill"    => $order->code,
-                    "consignee_name"    => $order->consignee_name,
-                    "consignee_phone"   => $order->consignee_phone,
-                    "commodity_amount"  => $amount,
-                    "logistic_bill"     => rtrim($logistic_bill,","),
-                    "volume"            => $volume,
-                    "weight"            => $weight,
+                $GLOBALS["FEE_INFO"] = [];
+                list($id,$money,$workTaxFee) = $service->matching($order,Feature::MAPPING["order"],$order->owner_id);
+                //数据组装
+                OwnerFeeDetail::query()->where("id",$this->detail->id)->update([
+                    "commodity_amount"  => $logisticInfo["amount"],
+                    "logistic_bill"     => $logisticInfo["logisticBill"],
+                    "volume"            => $logisticInfo["volume"],
+                    "weight"            => $logisticInfo["weight"],
                     "logistic_id"       => $order->logistic_id,
                     "work_fee"          => $money,
                     "owner_price_operation_id"  => $id,
-                    "logistic_fee"      => $logistic_fee,
+                    "logistic_fee"      => $logisticInfo["logisticFee"],
+                    "created_at"        => date('Y-m-d H:i:s'),
+                    "outer_id"          => $order->id,
+                    "outer_table_name"  => "orders",
                     "work_tax_fee"      => $workTaxFee,
-                    "logistic_tax_fee"  => $logistic_fee ? $logisticTaxFee : null,
+                    "logistic_tax_fee"  => $logisticInfo["logisticTaxFee"],
                 ]);
+                //向指定表插入标记 TODO
+                //if ($logisticInfo["logisticFee"] && $logisticInfo["fee_info"])OwnerFeeExpress::query()->insert($logisticInfo["fee_info"]);
+                /*if ($money>0)app("StoreService")->constructFeeInfo([
+                    "worked_at" => $order->wms_edittime ?: $order->updated_at,
+                    "owner_id" => $order->owner_id,
+                    "model_id"  => $id,
+                    "source_number"=> $order->client_code,
+                    "doc_number"   => $order->code,
+                    "commodity_id" => 0,
+                    "total_fee"    =>0,
+                    "tax_rate"     =>0,
+                    "fee_description"=>'',
+                ]);*/
+                //后续处理
                 OwnerFeeDetailLogistic::query()->where("owner_fee_detail_id",$this->detail->id)->delete();
-                foreach ($items as &$item)$item["owner_fee_detail_id"] = $this->detail->id;
-                if (count($items)>1)OwnerFeeDetailLogistic::query()->insert($items);
-                app("OrderService")->setOrderQuantity($order->owner_id,$order->logistic_id);
+                foreach ($logisticInfo["items"] as &$item)$item["owner_fee_detail_id"] = $this->detail->id;
+                if (count($logisticInfo["items"])>1)OwnerFeeDetailLogistic::query()->insert($logisticInfo["items"]);
                 break;
             case "processes":
-
                 $process = Process::query()->with("processStatistic")->find($this->detail->outer_id);
                 $this->detail->update([
                     "work_fee"  => $process->processStatistic ? $process->processStatistic->revenue : null,
                 ]);
                 break;
             case "waybills":
-
+                /** @var \stdClass $waybill */
                 $waybill = Waybill::query()->find($this->detail->outer_id);
+                if (!$waybill)break;
                 $waybill->loadMissing(["destinationCity","order.owner"]);
                 if (!$waybill->destinationCity && !$waybill->order)break;
-
                 $owner_id = $waybill->order->owner_id ?? $waybill->owner_id;
-                $detail = OwnerFeeDetail::query()->where("type","发货")
-                    ->where("owner_id",$owner_id)->whereIn("operation_bill",[$waybill->wms_bill_number,$waybill->waybill_number])->first();
-
-                if ($detail && $detail->logistic_fee !== null)break;
-
                 if ($waybill->type == "专线"){
-
+                    $provinceId = $waybill->order ? app("ProvinceService")->getProvince($waybill->order->province) : $waybill->destinationCity->province_id;
+                    $cityId = $waybill->destination_city_id;
+                    $consigneeName = $waybill->order ? $waybill->order->consignee_name : $waybill->recipient;
+                    $consigneePhone = $waybill->order ? $waybill->order->consignee_phone : $waybill->recipient_mobile;
+                    $GLOBALS["FEE_INFO"] = [
+                        "province_id" => $provinceId,
+                        "owner_id"  => $waybill->owner_id,
+                        "city_id"   => $cityId,
+                        "logistic_id" => $waybill->logistic_id,
+                        "order_number" => $waybill->wms_bill_number,
+                        "recipient_name"=>$consigneeName,
+                        "recipient_phone"=>$consigneePhone,
+                        "quantity"=>$waybill->carrier_weight_other,
+                        "unit_id"=>$waybill->carrier_weight_unit_id_other,
+                        "remark"=>$waybill->ordering_remark,
+                        "created_at"=>$waybill->updated_at,
+                    ];
+                    /** @var OwnerPriceLogisticService $service */
                     $service = app("OwnerPriceLogisticService");
                     list($fee,$taxFee) = $service->matching($waybill->carrier_weight_other,$owner_id,$waybill->logistic_id,
-                        $waybill->carrier_weight_unit_id_other,$waybill->order ? app("RegionService")->getProvince($waybill->order->province) : $waybill->destinationCity->province_id,
-                        $waybill->destination_city_id);
+                        $waybill->carrier_weight_unit_id_other,$provinceId, $cityId);
+                    //$this->buildWaybillFeeInfo(); TODO
                 }else{
-
+                    /** @var OwnerPriceDirectLogisticService $service */
                     $service = app("OwnerPriceDirectLogisticService");
                     list($fee,$taxFee) = $service->matching($waybill->mileage,$owner_id,$waybill->carType_id);
                 }
-                $this->detail->update([
+                $obj = [
                     "logistic_fee" => $fee,
                     "logistic_tax_fee" => $taxFee,
-                ]);
+                ];
+                app("OwnerFeeDetailService")->updateFind($this->detail,$obj);
                 break;
             case "stores":
-
+                /** @var \stdClass $store */
                 $store = Store::query()->find($this->detail->outer_id);
-                if (!$store || $store->status != "已入库") break;
+                if (!$store)break;
                 $store->loadMissing(["storeItems.commodity","warehouse"]);
-
-
+                /** @var OwnerPriceOperationService $service */
                 $service = app("OwnerPriceOperationService");
+                $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 (($this->detail->commodity_amount - $amount)!==0)app("StoreService")->setStoreAmount($store->owner_id,$this->detail->commodity_amount - $amount);
                 $this->detail->update([
-                    "owner_id" => $store->owner_id,
-                    "worked_at" => $store->updated_at,
-                    "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,
-                    "work_tax_fee" => $taxFee
+                    "work_tax_fee" => $taxFee,
                 ]);
+               /* if ($money>0)$this->constructFeeInfo([
+                    "worked_at" => $store->updated_at,
+                    "owner_id" => $store->owner_id,
+                    "model_id"  => $id,
+                    "source_number"=> null,
+                    "doc_number"   => $store->asn_code,
+                    "commodity_id" => 0,
+                    "total_fee"    =>0,
+                    "tax_rate"     =>0,
+                    "fee_description"=>'',
+                ]);*/
                 break;
             case "rejected_bills":
-                $rejectedBill = RejectedBill::query()->find($this->detail->outer_id);
-
+                /** @var \stdClass $rejectedBill */
                 $number = array_column(StoreRejected::query()->where("logistic_number_return",$rejectedBill->logistic_number_return)->get()->toArray(),"store_id");
 
                 foreach (Store::query()->with("storeItems")->whereIn("id",$number)->get() as $store){
-
+                    /** @var OwnerPriceOperationService $service */
                     $service = app("OwnerPriceOperationService");
+                    $GLOBALS["FEE_INFO"] = [];
                     list($id,$money,$taxFee) = $service->matching($store, Feature::MAPPING["store"], $store->owner_id, "入库",0);
-                    $bill = OwnerFeeDetail::query()->where("outer_id",$store->id)->where("outer_table_name","stores")->first();
-                    if ($bill) $bill->update([
-                        "work_fee" => $money,
-                        "owner_price_operation_id" => $id,
-                        "outer_id" => $rejectedBill->id,
-                        "outer_table_name" => "rejected_bills",
-                    ]); else app("OwnerFeeDetailService")->create([
-                        "owner_id" => $store->owner_id,
-                        "worked_at" => $store->created_at,
-                        "type" => "收货",
-                        "operation_bill" => $store->asn_code,
-                        "commodity_amount" => array_sum(array_column($store->storeItems->toArray(), "amount")),
+                    app("StoreService")->clearFeeInfo($store->asn_code);
+                    $this->detail->update([
                         "work_fee" => $money,
                         "owner_price_operation_id" => $id,
-                        "created_at" => date('Y-m-d H:i:s'),
-                        "outer_id" => $rejectedBill->id,
-                        "outer_table_name" => "rejected_bills",
                         "work_tax_fee" => $taxFee,
                     ]);
+                    app("StoreService")->constructFeeInfo([
+                        "worked_at" => $rejectedBill->updated_at,
+                        "owner_id" => $rejectedBill->id_owner,
+                        "model_id"  => $id,
+                        "source_number"=> null,
+                        "doc_number"   => $store->asn_code,
+                        "commodity_id" => 0,
+                        "total_fee"    =>0,
+                        "tax_rate"     =>0,
+                        "fee_description"=>'',
+                    ]);
                 }
-        }*/
+        }
     }
 }

+ 0 - 1
app/Notifications/RoutineNotification.php

@@ -46,7 +46,6 @@ class RoutineNotification extends Notification implements ShouldQueue
 
     public function toBroadcast($notifiable):BroadcastMessage
     {
-        Log::debug("notifiable",["开始分发通知"]);
         return new BroadcastMessage($this->seeLog);
     }
 }

+ 9 - 9
app/OwnerFeeExpress.php

@@ -16,16 +16,16 @@ class OwnerFeeExpress extends Model
         "province_id",
         "logistic_id",
         "logistic_number",
-        "weight",
-        "initial_weight",
-        "initial_weight_price",
-        "additional_weight",
-        "additional_weight_amount",
-        "additional_weight_price",
-        "total_fee",
-        "tax_rate",
+        "weight",//重量
+        "initial_weight",//首重
+        "initial_weight_price",//首重价格
+        "additional_weight",//续重
+        "additional_weight_amount",//续重数量,
+        "additional_weight_price",//续重价格
+        "total_fee",//总费用
+        "tax_rate",//税率
         "created_at",
-        "owner_id"
+        "owner_id"//货主
     ];
 
     public function province(): BelongsTo

+ 15 - 0
app/OwnerLogisticFeeReport.php

@@ -26,6 +26,11 @@ class OwnerLogisticFeeReport extends Model
         'tax_fee',//税费
         'owner_id'//货主
     ];
+
+        protected $appends = [
+            'initial_weight_fee',
+            'additional_weight_fee'
+        ];
     public $timestamps = false;
 
     public function logistic(): BelongsTo
@@ -37,5 +42,15 @@ class OwnerLogisticFeeReport extends Model
     {
         return $this->belongsTo(Province::class);
     }
+
+    public function getInitialWeightFeeAttribute(): string
+    {
+        return number_format($this->initial_weight * $this->initial_weight_price * $this->initial_amount, 2);
+    }
+
+    public function getAdditionalWeightFeeAttribute(): string
+    {
+        return number_format($this->additional_weight * $this->additional_price * $this->additional_amount, 2);
+    }
 }
 

+ 20 - 71
app/Services/OrderPackageReceivedSyncService.php

@@ -23,15 +23,14 @@ class OrderPackageReceivedSyncService
 
     /**
      * 同步快递信息
-     * 1 如果当前时间大于初始化时间 每日执行一次,更新order_packages中创建时间大于初始化时间,没有异常,用户未收货的全部订单的快递路由状态
-     * 2 如果当前时间小于等于初始化时间,执行初始化脚本,将数据库中全部小于等于初始化时间的数据更新
-     * @throws Exception
+     * @param bool $is_to_init 是否为初始化数据状态 初始化同步一个月的 正常执行为15天
+     * @param array $logistic_numbers 指定更新的单号
      */
     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, "同步快递信息定时方法", '');
+        //没有指定单号
         if (empty($logistic_numbers)) {
             $query = OrderPackage::query()
                 ->select(['logistic_number', 'order_id', 'id'])
@@ -40,14 +39,14 @@ class OrderPackageReceivedSyncService
                 }]);
             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 {
+        } else {//指定了单号
             $query = OrderPackage::query()
                 ->select(['logistic_number', 'order_id', 'id'])
                 ->with(['order' => function ($query) {
@@ -55,41 +54,34 @@ class OrderPackageReceivedSyncService
                 }])
                 ->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);
-            //sf
+            //更新顺丰系列
             if (array_key_exists('SF', $logisticNumbers)) {
                 $SFLogisticNumbers = $logisticNumbers['SF'];
-                //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-SF", json_encode($SFLogisticNumbers));
                 foreach ($SFLogisticNumbers as $logisticNumber) {
-                    //  LogService::log(OrderPackageReceivedSyncService::class, "同步SF快递单号", $logisticNumber);
                     LogisticSFSync::dispatch($logisticNumber);
                 }
             }
             //更新中通
             if (array_key_exists('ZTO', $logisticNumbers)) {
                 $ZTOLogisticNumbers = $logisticNumbers['ZTO'];
-                //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-ZTO", json_encode($ZTOLogisticNumbers));
                 foreach ($ZTOLogisticNumbers as $logisticNumber) {
-                    //  LogService::log(OrderPackageReceivedSyncService::class, "同步ZTO快递单号", $logisticNumber);
                     LogisticZopSync::dispatch($logisticNumber);
                 }
             }
             //更新韵达
             if (array_key_exists('YUNDA', $logisticNumbers)) {
                 $YDLogisticNumbers = $logisticNumbers['YUNDA'];
-                //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-YUNDA", json_encode($YDLogisticNumbers));
                 foreach ($YDLogisticNumbers as $logistic_number) {
-                    //  LogService::log(OrderPackageReceivedSyncService::class, "同步YUNDA快递单号", $logisticNumber);
                     LogisticYDSync::dispatch($logistic_number);
                 }
             }
             //更新圆通
             if (array_key_exists('YTO', $logisticNumbers)) {
                 $YTOLogisticNumbers = $logisticNumbers['YTO'];
-                //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-YTO", json_encode($YTOLogisticNumbers));
                 foreach ($YTOLogisticNumbers as $logistic_number) {
                     if ($logistic_number) LogisticYTOSync::dispatch($logistic_number);
                 }
@@ -97,8 +89,13 @@ class OrderPackageReceivedSyncService
         });
     }
 
-    public function syncLogisticRouteByAliJiSu($logistic_numbers = [])
+    /**
+     * 阿里云同步快递信息
+     * @param array $logistic_numbers 指定单号同步
+     */
+    public function syncLogisticRouteByAliJiSu(array $logistic_numbers = [])
     {
+        //没有指定单号
         if (empty($logistic_numbers)) {
             ini_set('max_execution_time', 2 * 60 * 60);
             $query = OrderPackage::query()
@@ -110,20 +107,17 @@ class OrderPackageReceivedSyncService
                 });
             $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days')))
                 ->whereNull('received_at');
-        } else {
+        } else {//指定了单号
             $query = OrderPackage::query()
                 ->select(['logistic_number', 'order_id', 'id'])
                 ->whereIn('logistic_number', $logistic_numbers);
         }
 
         $query->chunkById(200, function ($orderPackages) {
-            //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-阿里公用接口", json_encode($orderPackages));
             foreach ($orderPackages as $orderPackage) {
                 if ($orderPackage && $orderPackage->logistic_number) LogisticAliJiSuSync::dispatch($orderPackage->logistic_number);
             }
         });
-        //TODO 暂时不同步京东
-//        $this->syncLogisticRouteJD();
     }
 
     public function syncLogisticRouteJD()
@@ -139,59 +133,12 @@ class OrderPackageReceivedSyncService
         $query = $query->where('created_at', '>=', now()->subDays(config('api_logistic.querying_days')))
             ->whereNull('received_at')->where('logistic_number', 'like', 'JD%');
         $query->chunkById(200, function ($orderPackages) {
-            //  LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-JD", json_encode($orderPackages));
             foreach ($orderPackages as $orderPackage) {
                 if ($orderPackage && $orderPackage->logistic_number) LogisticAliJiSuSync::dispatch($orderPackage->logistic_number);
             }
         });
     }
 
-    /**
-     * 根据传递的承运商与快递单号更新快递信息
-     * @param array $logisticNumbers 快递单号
-     * example: ['SF' => ['SF1038651915891', 'SF1038651413847', 'SF1038611050071'],'ZT'=>['75424148714142','548464120822', '75424147834290']....]
-     * @throws Exception 快递接口调用或者返回的信息有误,无法更新指定的快递路由信息
-     */
-    public function syncLogisticRouteApi(array $logisticNumbers)
-    {
-        $this->update($this->getLogisticRoutes($logisticNumbers));
-    }
-
-    /**
-     * 获取快件揽收信息
-     * @param array $request [
-     * 'SF' => ['SF1038651915891', 'SF1038651413847', 'SF1038611050071'],
-     * 'ZT'=>['75424148714142','548464120822', '75424147834290']
-     * ]
-     * @return array
-     * @throws Exception
-     */
-    public function getLogisticRoutes(array $request): array
-    {
-        $this->logisticSFService = new LogisticSFService();
-        $resultSF = [];
-        $resultYD = [];
-        $resultYT = [];
-        $resultOther = [];
-        foreach ($request as $key => $logisticNums) {
-            switch ($key) {
-                case "SF":
-                    $resultSF = $this->logisticSFService->get($logisticNums);
-                    break;
-                case "YD":
-                    $resultYD = [];
-                    break;
-                case "YT":
-                    $resultYT = [];
-                    break;
-                default:
-                    $resultOther = [];
-                    break;
-            }
-        }
-        return array_merge($resultSF, $resultYD, $resultYT, $resultOther);
-    }
-
     /**
      * 根据快递单号更新状态
      * @param array $logisticResponses
@@ -211,11 +158,15 @@ class OrderPackageReceivedSyncService
                     unset($logisticResponse['status']);
                 }
             }
+            //设置异常信息
             $logisticResponse = $this->setExceptionStatus($logisticResponse);
+            //标记为单号异常
             if (Str::contains($orderPackage->logistic_number, ['SO', '#', '-'])) {
                 $logisticResponse['exception_status'] = '单号异常';
             }
-            if (((!isset($logisticResponse['status'])) || ($logisticResponse['status'] === '')) && $orderPackage->status === '') {
+            //没有状态的数据赋予初始状态
+            if (((!isset($logisticResponse['status'])) || ($logisticResponse['status'] === '')) &&
+                $orderPackage->status === '') {
                 $logisticResponse['status'] = '生成订单';
 
                 if (!empty($orderPackage->sent_at)) {
@@ -225,7 +176,6 @@ class OrderPackageReceivedSyncService
                     $logisticResponse['status'] = '已称重';
                 }
             }
-
             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']);
@@ -248,7 +198,6 @@ class OrderPackageReceivedSyncService
             try {
                 $logisticCode = $orderPackage->order->logistic->code;
             } catch (Exception $e) {
-                //  LogService::log(OrderPackageReceivedSyncService::class, "快递同步按照承运商分组异常", json_encode($orderPackage??[]));
                 continue;
             }
             $key = config('api_logistic.logistic.' . $logisticCode);

+ 55 - 20
app/Services/OrderPackageService.php

@@ -11,6 +11,7 @@ use App\Services\common\DataHandlerService;
 use Carbon\Carbon;
 use App\Traits\ServiceAppAop;
 use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Http\Client\Response;
 use Illuminate\Support\Facades\Http;
 
 
@@ -284,18 +285,28 @@ class OrderPackageService
                 continue;
             }
             if ($checktime) {
+                $this->checkingAndProcess($package); //检查和处理揽收
                 $update_params[] = [
                     'id' => $package->id,
                     'sent_at' => $checktime,
                 ];
-            } else {
-                continue;
             }
-
         }
         $this->batchUpdate($update_params);
     }
 
+    /**
+     * 检查和处理揽收
+     *
+     * @param OrderPackage $package
+     */
+    public function checkingAndProcess(OrderPackage $package)
+    {
+        //TODO 揽收与分配回馈时间不定 这里应该推进队列处理
+        //检查快递商来判断该快递商是否允许自动揽收发货
+        //检查揽收标记来判断是否已被揽收过
+    }
+
     /**
      * @param $orderHeaders
      * @return array
@@ -345,7 +356,9 @@ class OrderPackageService
     }
 
     /**
-     * 一键揽收上传
+     * 中通一键揽收上传
+     * 由于中通接口只支持100条的操作,本接口支持100以上
+     * 如果中途调用中通接口发生异常,本方法不会停止,但在最后会返回错误信息,将执行失败的单号和原因返回
      * @param $logistic_numbers array
      * @return array
      */
@@ -375,20 +388,20 @@ class OrderPackageService
 //            ];
 //        }
 
-        $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');
+        $url = env('APP_ENV') === 'production' ? config('api_logistic.collectUpload.ZTO.prod.url') : config('api_logistic.collectUpload.ZTO.test.url');
+        $xAppKey = env('APP_ENV') === 'production' ? config('api_logistic.collectUpload.ZTO.prod.x-appKey') : config('api_logistic.collectUpload.ZTO.test.x-appKey');
+        $appSecret = env('APP_ENV') === 'production' ? config('api_logistic.collectUpload.ZTO.prod.appSecret') : config('api_logistic.collectUpload.ZTO.test.appSecret');
+        $appId = env('APP_ENV') === 'production' ? config('api_logistic.collectUpload.ZTO.prod.appId') : config('api_logistic.collectUpload.ZTO.test.appId');
         //中通接口最大支持100条
         $logistic_numbers_chunked = array_chunk($logistic_numbers, 100);
+        //中通接口返回异常信息数组
         $errorMessage = [];
         foreach ($logistic_numbers_chunked as $logistic_numbers_chunked_items) {
             $orderPackages = OrderPackage::query()
                 ->select('weight', 'logistic_number')
                 ->whereIn('logistic_number', $logistic_numbers_chunked_items)->get();
-
+            //中通接口请求body
             $collectUploadDTOS = [];
-
             foreach ($orderPackages as $orderPackage) {
                 $collectUploadDTOS[] = [
                     'billCode' => $orderPackage->logistic_number,
@@ -397,16 +410,15 @@ class OrderPackageService
                     '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);
+            try {
+                $response = $this->sentReqToZOP($collectUploadDTOS, $appSecret, $xAppKey, $url);
+            } catch (\Exception $e) {
+                $errorMessage[] = [
+                    'status_code' => 'REQUEST_ERROR',
+                    'message' => [$e->getMessage()],
+                    'logistic_number' => $logistic_numbers_chunked_items,
+                ];
+            }
             $responseBody = json_decode($response->body());
             if ($responseBody->statusCode === 'S210' ||//无权限
                 $responseBody->statusCode === 'PARAM_ERROR' ||//揽收上传信息为空
@@ -415,6 +427,7 @@ class OrderPackageService
                 $errorMessage[] = [
                     'status_code' => $responseBody->statusCode,
                     'message' => $responseBody->message,
+                    'logistic_number' => $logistic_numbers_chunked_items,
                 ];
             }
         }
@@ -424,4 +437,26 @@ class OrderPackageService
             return ['success' => false, 'message' => $errorMessage];
         }
     }
+
+    /**
+     * 调用中通接口封装
+     * @param array $requestBody 请求体
+     * @param $appSecret
+     * @param $xAppKey
+     * @param $url
+     * @return Response
+     */
+    private function sentReqToZOP(array $requestBody, $appSecret, $xAppKey, $url): Response
+    {
+        $body = json_encode([
+            'collectUploadDTOS' => $requestBody,
+        ], 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,
+        ];
+        return Http::withHeaders($headers)->withBody($body, 'application/json')->post($url);
+    }
 }

+ 6 - 3
app/Services/OrderService.php

@@ -1547,11 +1547,12 @@ sql;
 
     /**
      * @param string $orderNo
+     * @param string|null $orderLineNo
      * @param string|null $warehouseCode
      * @param resource|null|mixed $conn
      * @return string
      */
-    public function allocation(string $orderNo, ?string $warehouseCode, $conn = null):string
+    public function allocation(string $orderNo, ?string $orderLineNo = null, ?string $warehouseCode = null, $conn = null):string
     {
         if (!$warehouseCode){
             $order = DB::connection("oracle")->selectOne(DB::raw("SELECT warehouseid FROM DOC_ORDER_HEADER WHERE ORDERNO = ?"),[$orderNo]);
@@ -1559,10 +1560,12 @@ sql;
             $warehouseCode = $order->warehouseid;
         }
         $user = Auth::user() ? "W".Auth::user()["name"] : "WAS";
+        $mode = $orderLineNo ? 'By OrderNO + OrderLineNO' : 'By OrderNO';
+        $lineNo = $orderLineNo ?: '0';
         $sql = <<<sql
 BEGIN
-    SPSO_HardAllocation_Process('{$warehouseCode}','Allocation','By OrderNO',
-                                 null,'{$orderNo}','0',null,
+    SPSO_HardAllocation_Process('{$warehouseCode}','Allocation','{$mode}',
+                                 null,'{$orderNo}','{$lineNo}',null,
     '{$user}',:CODE);
 END;
 sql;

+ 1 - 0
app/Services/RejectedBillService.php

@@ -359,6 +359,7 @@ class RejectedBillService
             if ($bill)app("StoreService")->clearFeeInfo($store->asn_code);
             if ($bill) $bill->update([
                     "work_fee" => $money,
+                    "work_tax_fee" => $taxFee,
                     "worked_at" => $rejectedBill->updated_at,
                     "owner_price_operation_id" => $id,
                     "outer_id" => $rejectedBill->id,

+ 86 - 20
app/Traits/LogisticSyncTrait.php

@@ -9,17 +9,23 @@ use function DeepCopy\deep_copy;
 
 trait LogisticSyncTrait
 {
+    /**
+     * 设置 status 与 exception_status
+     * @param array $data
+     * @return array
+     */
     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 === '无法获取路由') {//这种类型的单,不需要再更新状态
+            $orderPackage->exception_status === '无法获取路由') {
             return $data;
         }
         /** @var \Carbon\Carbon $sent_at */
@@ -40,7 +46,7 @@ trait LogisticSyncTrait
             if (empty($transfer_status)) {//没有路由信息
                 //延迟发货
                 $created_at_clone = deep_copy($created_at);
-                if ($created_at->gt($created_at_clone->startOfDay()->addHours(16)->addMinutes(30))) {//下午16的单
+                if ($created_at->gt($created_at_clone->startOfDay()->addHours(16)->addMinutes(30))) {//下午16.30的单
                     $created_at_clone = deep_copy($created_at);
                     if ($created_at_clone->addDay()->endOfDay()->lt(now())) {//超过第二天的24时
                         $created_at_clone = deep_copy($created_at);
@@ -53,9 +59,6 @@ trait LogisticSyncTrait
                         $data['is_delay_deliver'] = true;
                     }
                 }
-            } else {
-                //虚拟揽件
-//                $data['exception_status'] = '虚拟揽件'; //没有复核但是有路由信息   21-09-10 取消虚拟揽件状态
             }
         } else {//复核过
             if (empty($transfer_status)) {//没有路由信息
@@ -69,19 +72,15 @@ trait LogisticSyncTrait
                     }
                 }
             } 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 = empty(!$transfer_status[0]['remark']) ? $transfer_status[0]['remark'] : $transfer_status[0]['accept_address'];
+                $transfer_status = $this->sortTransferStatusByAcceptTimeDESC($transfer_status);
+                $last_transfer_accept_time = $transfer_status[0]['accept_time'];
+                $last_remark = $this->getLastRemark($transfer_status[0]);
                 if (count($transfer_status) < 3) {//三条以内的不管地区 时间限制为24h
-                    if (Carbon::parse($last_transfer)->diffInHours(now()) > 24) {
+                    if (Carbon::parse($last_transfer_accept_time)->diffInHours(now()) > 24) {
                         $data['exception_status'] = '在途异常';
                     }
                 } else {
+                    //根据地区获取超时时间限制
                     $SHORT_RESPONSE_HOURS = (function ($province) {
                         switch ($province) {
                             case '浙江省':
@@ -122,23 +121,90 @@ trait LogisticSyncTrait
                                 return 24;
                         }
                     })($orderPackage->order->province);
-                    if (Carbon::parse($last_transfer)->diffInHours(now()) > $SHORT_RESPONSE_HOURS) {
+                    if (Carbon::parse($last_transfer_accept_time)->diffInHours(now()) > $SHORT_RESPONSE_HOURS) {
                         $data['exception_status'] = '在途异常';
                     }
                 }
-                if (($data['exception_status'] ?? '' === '在途异常') && ($data['status'] ?? '' === '派送中')) {//在途异常修正为派送异常
+                //在途异常修正为派送异常
+                if (($data['exception_status'] ?? '' === '在途异常') && ($data['status'] ?? '' === '派送中')) {
                     $data['exception_status'] = '派送异常';
                 }
+                //内容中有一下信息的,视为签收
                 if (Str::contains($last_remark, ['代收', '快递柜', '驿站', '自提柜', '丰巢', '快递小屋', '合作点', '快递超市', '签收'])) {
-                    $data['exception_status'] = '';
-                    $data['status'] = '已签收';
+                    $data = $this->setStatus已签收($data, $last_transfer_accept_time);
                 }
             }
         }
         //如果复核时间>前一天的18.00,则不添加异常信息
-        if ((!empty($sent_at)) &&($sent_at->gt(now()->subDay()->startOfDay()->addHours(18))) && isset($data['exception_status'])) {
+        if ((!empty($sent_at)) &&
+            ($sent_at->gt(now()->subDay()->startOfDay()->addHours(18))) &&
+            isset($data['exception_status'])) {
             unset($data['exception_status']);
         }
+        //邮政待揽收状态不是在途
+        $logistic_id = $orderPackage->order->logistic_id ?? null;
+        //判断承运商是否为邮政
+        $data = $this->邮政实际待揽收由在途改为已复核($logistic_id, $transfer_status, $data);
+        return $data;
+    }
+
+    /**
+     * 按照accept_time倒序排序
+     * @param $transfer_status
+     * @return mixed
+     */
+    private function sortTransferStatusByAcceptTimeDESC($transfer_status)
+    {
+        usort($transfer_status, function ($a, $b) {
+            if ($a['accept_time'] === $b['accept_time']) {
+                return 0;
+            }
+            return ($a['accept_time'] > $b['accept_time']) ? -1 : 1;
+        });
+        return $transfer_status;
+    }
+
+    /**
+     * 获取最新一条路由信息的remark
+     * @param $transfer_status
+     * @return mixed
+     */
+    private function getLastRemark($transfer_status)
+    {
+        //部分接口的remark在accept_address字段中
+        return empty(!$transfer_status['remark']) ? $transfer_status['remark'] : $transfer_status['accept_address'];
+    }
+
+    /**
+     * @param array $data
+     * @param $last_transfer_accept_time
+     * @return array
+     */
+    private function setStatus已签收(array $data, $last_transfer_accept_time): array
+    {
+        $data['exception_status'] = '';
+        $data['status'] = '已签收';
+        $data['received_at'] = $last_transfer_accept_time;
+        return $data;
+    }
+
+    /**
+     * @param $logistic_id
+     * @param $transfer_status
+     * @param array $data
+     * @return array
+     */
+    private function 邮政实际待揽收由在途改为已复核($logistic_id, $transfer_status, array $data): array
+    {
+        if ((!empty($logistic_id)) && ($logistic_id === 6 || $logistic_id === 88)) {
+            if (!empty($transfer_status)) {
+                $this->sortTransferStatusByAcceptTimeDESC($transfer_status);
+                $last_remark = $this->getLastRemark($transfer_status);
+                if (Str::contains($last_remark, ['等待揽收', '商品已下单'])) {
+                    $data['status'] = '已复核';
+                }
+            }
+        }
         return $data;
     }
 }

+ 1 - 1
database/factories/OrderPackageFactory.php

@@ -22,11 +22,11 @@ $factory->define(OrderPackage::class, function (Faker $faker) {
         'sent_at' => now()->subHours(1),
         'received_at' => null,
         'transfer_status' => null,
-        'remark' => null,
         'owner_id' => random_int(1, 100),
         'uploaded_to_wms' => '是',
         'sync_routes_flag' => false,
         'is_manual_update' => false,
         'exception_status' => random_int(1,6),
+        'is_delay_deliver' => false,
     ];
 });

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

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ChangeAuthoritiesTableAddColumnRoute extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table("authorities",function (Blueprint $table){
+            $table->string("route")->nullable()->comment("路由");
+            $table->bigInteger("method")->nullable()->comment("请求方式");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table("authorities",function (Blueprint $table){
+            $table->dropColumn("route");
+            $table->dropColumn("method");
+        });
+    }
+}

+ 1 - 1
resources/views/finance/_resetInstantBill.blade.php

@@ -7,7 +7,7 @@
             <div class="modal-body">
                 <label class="row">
                     <span class="col-2">日期</span>
-                    <input type="date" class="form-control col-4" v-model="reset.startDate">
+                    <input type="date" class="form-control col-4 ml-3" v-model="reset.startDate">
                     <span class="mt-1">&nbsp;━━━&nbsp;</span>
                     <input type="date" class="form-control col-4" v-model="reset.endDate" :min="reset.startDate">
                 </label>

+ 2 - 1
resources/views/finance/instantBill.blade.php

@@ -32,7 +32,8 @@
                 <a class="dropdown-item" @click="billExport(true)" href="javascript:">导出所有页</a>
             </div>
             @include("finance._resetInstantBill")
-            {{--@can("结算管理-即时账单-重置即时账单")<button data-toggle="modal" data-target="#resetInstantBill" class="btn btn-sm btn-outline-primary">重置即时账单</button>@endcan--}}
+            @can("结算管理-即时账单-重置即时账单")<button data-toggle="modal" data-target="#resetInstantBill"
+                                            class="btn btn-sm btn-outline-primary">重置即时账单</button>@endcan
         </div>
         <div>
             <table class="table table-sm text-nowrap td-min-width-80" id="table">

+ 10 - 2
resources/views/finance/settlementBills/expressFee/report/index.blade.php

@@ -89,8 +89,12 @@
                     <td>@{{ report.province.name }}</td>
                     <td>@{{ report.initial_weight }}</td>
                     <td>@{{ report.initial_amount }}</td>
+                    <td>@{{ report.initial_weight_price }}</td>
+                    <td>@{{ report.initial_weight_fee }}</td>
                     <td>@{{ report.additional_weight }}</td>
                     <td>@{{ report.additional_amount }}</td>
+                    <td>@{{ report.additional_price }}</td>
+                    <td>@{{ report.additional_weight_fee }}</td>
                     <td>@{{ report.fee }}</td>
                 </tr>
             </table>
@@ -191,9 +195,13 @@
                     {name: 'logistic.name', value: '快递公司'},
                     {name: 'province', value: '地区'},
                     {name: 'initial_weight', value: '首重'},
-                    {name: 'initial_amount', value: '订单数'},
+                    {name: 'initial_amount', value: '首重数量'},
+                    {name: 'initial_weight_price', value: '首重价格'},
+                    {name: 'initial_weight_fee', value: '首重费用'},
                     {name: 'additional_weight', value: '续重'},
-                    {name: 'additional_amount', value: '续重合计'},
+                    {name: 'additional_amount', value: '续重数量'},
+                    {name: 'additional_price', value: '续重价格'},
+                    {name: 'additional_weight_fee', value: '续重费用'},
                     {name: 'fee', value: '(省份)合计'},
                 ];
                 new Header({

+ 9 - 2
resources/views/layouts/notification.blade.php

@@ -14,7 +14,7 @@
             width: 100%;
         }
         body{
-            width: 510px;
+            width: 100%;
             margin : 0 auto;
         }
         .b-container{
@@ -165,7 +165,14 @@
                     this.playAudio(notification.mark);
                     if(window.Notification ) {
                         Notification.requestPermission(function(status) {
-                            new Notification('通知面板', { body: '有新工单' });
+                            let notify = new Notification('通知面板', { body: '有新工单',icon:"{{asset('icon/faviconc.ico')}}" });
+                            notify.onclick=function(){
+                                //如果通知消息被点击,通知窗口将被激活
+                                window.focus();
+                                notify.close();
+                                //打开对应的界面
+                                window.open('{{url('')}}'+'/'+notification.link);
+                            };
                         });
                     }
                 },

+ 91 - 0
tests/Services/OrderPackageReceivedSyncService/TestSetExceptionStatus.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace Tests\Services\OrderPackageReceivedSyncService;
+
+use App\OrderPackage;
+use App\Services\OrderPackageReceivedSyncService;
+use Carbon\Carbon;
+use Illuminate\Foundation\Testing\RefreshDatabase;
+use Tests\TestCase;
+
+class TestSetExceptionStatus extends TestCase
+{
+    protected $order_package_ids;
+
+    /** @var OrderPackageReceivedSyncService $service */
+    public $service;
+
+    function setUp(): void
+    {
+        parent::setUp();
+        $this->service = app(OrderPackageReceivedSyncService::class);
+    }
+
+    public function testReturned()
+    {
+        $this->assertTrue(true);
+    }
+
+    function tearDown(): void
+    {
+        OrderPackage::destroy($this->order_package_ids);
+        parent::tearDown();
+    }
+
+    /**
+     * @test
+     */
+    public function test_邮政待揽收_改_已复核()
+    {
+        $logistic_number = 'GM000001';
+        OrderPackage::query()->where('logistic_number', $logistic_number)->delete();
+
+        $order =  factory(\App\Order::class)->create([
+            'logistic_id' => 6
+        ]);
+
+        $orderPackage = factory(OrderPackage::class)->create([
+            'order_id' => $order->id,
+            'logistic_number' => $logistic_number,
+        ]);
+        $data = [
+            'logistic_number' => $logistic_number,
+            'status' => '在途',
+            'transfer_status' => [
+                [
+                    'accept_time' => now()->subHours(5)->toDateTimeString(),
+                    'accept_address' => '等待揽收中',
+                    'remark' => '',
+                ],
+                [
+                    'accept_time' => now()->subHours(2)->toDateTimeString(),
+                    'accept_address' => '商品已下单',
+                    'remark' => '',
+                ],
+            ],
+        ];
+        $res =  $this->service->setExceptionStatus($data);
+        $this->assertEquals('已复核',$res['status']);
+    }
+
+
+    public function test_如果复核时间大于前一天的18时,则不添加异常信息()
+    {
+        $logistic_number = 'GM000001';
+        OrderPackage::query()->where('logistic_number', $logistic_number)->delete();
+
+
+        $orderPackage = factory(OrderPackage::class)->create([
+            'logistic_number' => $logistic_number,
+            'sent_at' => now()->subDay()->startOfDay()->addHours(19),
+        ]);
+        $data = [
+            'logistic_number' => $logistic_number,
+            'status' => '在途',
+            'exception_status' => '在途异常',
+            'transfer_status' => [],
+        ];
+        $res =  $this->service->setExceptionStatus($data);
+        $this->assertEquals(false,isset($res['exception_status']));
+    }
+}