Browse Source

Merge branch 'Haozi' into turnaround

# Conflicts:
#	app/Services/OrderService.php
#	resources/views/order/index/delivering.blade.php
haozi 4 years ago
parent
commit
f8e75dc4f7
100 changed files with 3352 additions and 1022 deletions
  1. 2 0
      .gitignore
  2. 11 0
      apidoc.json
  3. 2 2
      app/Console/Commands/CreateProcurementTotalBill.php
  4. 2 2
      app/Console/Kernel.php
  5. 1 1
      app/Events/OrderIssueProcessLogCreateEvent.php
  6. 1 2
      app/Exceptions/Handler.php
  7. 75 19
      app/Filters/OrderPackageFilters.php
  8. 89 10
      app/Filters/WorkOrderFilters.php
  9. 87 0
      app/Http/ApiControllers/LoginController.php
  10. 12 1
      app/Http/Controllers/Auth/RegisterController.php
  11. 13 11
      app/Http/Controllers/ControlPanelController.php
  12. 13 1
      app/Http/Controllers/HandInStorageController.php
  13. 3 5
      app/Http/Controllers/InventoryAccountController.php
  14. 2 2
      app/Http/Controllers/LaborCompanyController.php
  15. 1 0
      app/Http/Controllers/LaborReportController.php
  16. 12 17
      app/Http/Controllers/MeasureMonitorController.php
  17. 2 3
      app/Http/Controllers/OrderController.php
  18. 16 8
      app/Http/Controllers/OrderIssueProcessLogController.php
  19. 23 1
      app/Http/Controllers/OrderPackageController.php
  20. 14 0
      app/Http/Controllers/OrderPackageExpressBillPrintRecordController.php
  21. 1 0
      app/Http/Controllers/OwnerController.php
  22. 84 0
      app/Http/Controllers/OwnerGroupController.php
  23. 77 46
      app/Http/Controllers/PackageLogisticController.php
  24. 40 0
      app/Http/Controllers/PrintController.php
  25. 3 49
      app/Http/Controllers/PrintPartController.php
  26. 64 0
      app/Http/Controllers/PrintPartImageController.php
  27. 46 15
      app/Http/Controllers/PrintTemplateController.php
  28. 5 7
      app/Http/Controllers/ProcessController.php
  29. 3 2
      app/Http/Controllers/RejectedBillController.php
  30. 1 0
      app/Http/Controllers/RejectedBillItemController.php
  31. 11 1
      app/Http/Controllers/RequirementController.php
  32. 2 2
      app/Http/Controllers/SettlementBillExpressFeeDetailController.php
  33. 1 1
      app/Http/Controllers/SettlementBillExpressFeeReportController.php
  34. 0 1
      app/Http/Controllers/SettlementBillStoreFeeDetailController.php
  35. 0 3
      app/Http/Controllers/StorageController.php
  36. 5 2
      app/Http/Controllers/StoreController.php
  37. 73 0
      app/Http/Controllers/TerminalController.php
  38. 62 0
      app/Http/Controllers/TerminalPrinterController.php
  39. 252 77
      app/Http/Controllers/TestController.php
  40. 57 4
      app/Http/Controllers/UserController.php
  41. 244 42
      app/Http/Controllers/WaybillController.php
  42. 63 118
      app/Http/Controllers/WorkOrderController.php
  43. 1 6
      app/Http/Controllers/api/thirdPart/flux/SortingController.php
  44. 3 1
      app/Http/Controllers/api/thirdPart/goodscan/PackageController.php
  45. 2 0
      app/Http/Controllers/api/thirdPart/hengli/PackageController.php
  46. 2 0
      app/Http/Controllers/api/thirdPart/weight/PackageController.php
  47. 4 0
      app/Http/Controllers/api/thirdPart/weight/WeightBaseController.php
  48. 3 3
      app/Http/Kernel.php
  49. 53 0
      app/Http/Middleware/AuthorizingApi.php
  50. 1 1
      app/Http/Middleware/DecodingRequest.php
  51. 6 11
      app/Http/Middleware/LogPostRequest.php
  52. 30 0
      app/Http/Requests/Printer/TerminalPrinterRequest.php
  53. 24 0
      app/Http/Requests/Printer/TerminalRequest.php
  54. 10 6
      app/Http/Requests/RequirementRequest.php
  55. 49 31
      app/Jobs/CacheShelfTaskJob.php
  56. 11 9
      app/Jobs/SettlementBillReportTask.php
  57. 2 1
      app/Jobs/WeightUpdateInstantBill.php
  58. 1 1
      app/Listeners/UpdateOrderPackageExceptionListener.php
  59. 34 0
      app/Logging/CriticalFormatter.php
  60. 23 0
      app/Logging/DebugFormatter.php
  61. 34 0
      app/Logging/ErrorFormatter.php
  62. 16 0
      app/Logging/Handler/EmailHandler.php
  63. 18 0
      app/Logging/InfoFormatter.php
  64. 18 0
      app/Logging/WarningFormatter.php
  65. 1 1
      app/OracleActAllocationDetails.php
  66. 7 0
      app/OracleDOCOrderHeader.php
  67. 46 0
      app/OracleDocOrderDeliveryInfo.php
  68. 4 0
      app/OracleInvLotLocId.php
  69. 6 0
      app/Order.php
  70. 7 2
      app/OrderIssue.php
  71. 6 3
      app/OrderIssueProcessLog.php
  72. 226 146
      app/OrderPackage.php
  73. 26 0
      app/OrderPackageExpressBillPrintRecords.php
  74. 2 1
      app/Owner.php
  75. 20 0
      app/OwnerGroup.php
  76. 30 0
      app/OwnerLogisticPrintTemplate.php
  77. 25 0
      app/PrintPartImage.php
  78. 11 0
      app/PrintTemplate.php
  79. 86 46
      app/Providers/AppServiceProvider.php
  80. 12 13
      app/Providers/EventServiceProvider.php
  81. 6 1
      app/Providers/RouteServiceProvider.php
  82. 2 0
      app/Requirement.php
  83. 20 4
      app/Services/CacheShelfService.php
  84. 112 0
      app/Services/DeliveryService.php
  85. 165 0
      app/Services/Express/CaiNiaoExpress.php
  86. 52 0
      app/Services/Express/ExpressInterface.php
  87. 68 0
      app/Services/Express/PDDExpress.php
  88. 16 7
      app/Services/ForeignHaiRoboticsService.php
  89. 302 185
      app/Services/HandInStorageService.php
  90. 33 0
      app/Services/Interfaces/DeliveryInterface.php
  91. 14 0
      app/Services/InventoryAccountService.php
  92. 95 0
      app/Services/JDDeliveryService.php
  93. 27 0
      app/Services/LaborCompanyService.php
  94. 3 14
      app/Services/LogisticAliJiSuApiService.php
  95. 5 23
      app/Services/LogisticSFService.php
  96. 5 21
      app/Services/LogisticYDService.php
  97. 3 14
      app/Services/LogisticYTOService.php
  98. 5 16
      app/Services/LogisticZopService.php
  99. 35 0
      app/Services/MeasureMonitorService.php
  100. 49 0
      app/Services/OrderIssueService.php

+ 2 - 0
.gitignore

@@ -13,6 +13,8 @@
 /storage/*.key
 /vendor
 .env
+private.pem
+public.pem
 .env.backup
 .phpunit.result.cache
 Homestead.json

+ 11 - 0
apidoc.json

@@ -0,0 +1,11 @@
+{
+    "name": "bswas",
+    "description": "WMS API interface doc",
+    "title": "",
+    "url" : "https://was.baoshi56.com/api/v1",
+    "sampleUrl": "https://was.baoshi56.com/api/v1",
+    "template": {
+        "withCompare": true,
+        "withGenerator": true
+    }
+}

+ 2 - 2
app/Console/Commands/CreateProcurementTotalBill.php

@@ -43,10 +43,10 @@ class CreateProcurementTotalBill extends Command
     {
         $date=$this->getDate();
         $procurementCheckSheets=ProcurementCheckSheet::query()
-            ->selectRaw('procurements.supplier_id supplier_id,procurement_check_sheets.created_at created_at,procurement_check_sheets.status status,SUM(procurement_check_sheets.account_payable) account_payable')
+            ->selectRaw('procurements.supplier_id supplier_id,procurement_deliveries.signed_at signed_at,procurement_check_sheets.status status,SUM(procurement_check_sheets.account_payable) account_payable')
             ->leftJoin('procurement_deliveries','procurement_check_sheets.procurement_delivery_id','procurement_deliveries.id')
             ->leftJoin('procurements','procurement_deliveries.procurement_id','procurements.id')
-            ->where('procurement_check_sheets.created_at','like',$date."%")
+            ->where('procurement_deliveries.signed_at','like',$date."%")
             ->groupBy('supplier_id')
             ->get();
         $totalBill=[];

+ 2 - 2
app/Console/Kernel.php

@@ -71,9 +71,9 @@ class  Kernel extends ConsoleKernel
         $schedule->command('beforeCreateOwnerReport')->monthlyOn(1);
         $schedule->command('sync:batch')->everyMinute();
         $schedule->command('sync:order')->everyMinute();
-        $schedule->command('syncOrderPackageLogisticRouteTask')->dailyAt('1:20');//同步快递信息到orderPackage
+        $schedule->command('syncOrderPackageLogisticRouteTask')->dailyAt('6:01');//同步快递信息到orderPackage
         $schedule->command('syncOrderPackageLogisticRouteTask')->dailyAt('12:01');//同步快递信息到orderPackage
-        $schedule->command('updateOrderPackageExceptionTypeCountingRecordTask')->dailyAt('2:20');//更新OrderPackageExceptionTypeCountingRecord
+//        $schedule->command('updateOrderPackageExceptionTypeCountingRecordTask')->dailyAt('2:20');//更新OrderPackageExceptionTypeCountingRecord
         $schedule->command('SyncWmsCommoditiesInformation')->everyMinute();
         $schedule->command('clear:cancelledOrder')->everyMinute();
         $schedule->command('WasSyncWmsAsnInformation')->everyMinute();

+ 1 - 1
app/Events/OrderIssueProcessLogCreateEvent.php

@@ -18,7 +18,7 @@ class OrderIssueProcessLogCreateEvent
     /**
      * @var int
      * 1 返回派件
-     * 2 已收
+     * 2 已
      */
     public $status;
 

+ 1 - 2
app/Exceptions/Handler.php

@@ -35,7 +35,7 @@ class Handler extends ExceptionHandler
      *
      * @param Throwable $exception
      * @return void
-     * @throws Exception
+     * @throws Exception|Throwable
      */
     public function report(Throwable $exception)
     {
@@ -89,7 +89,6 @@ class Handler extends ExceptionHandler
                 return response()->json($exception->errors(),200,[],JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
             }
             if(strpos($exception->getMessage(),'This action is unauthorized')!==false){
-                dd(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
                 return response()->view('exception.unauthorized');
             }
             if (method_exists($exception,'getStatusCode')) {

+ 75 - 19
app/Filters/OrderPackageFilters.php

@@ -3,6 +3,7 @@
 
 namespace App\Filters;
 
+use App\OracleDOCOrderHeader;
 use App\Order;
 use App\OrderIssue;
 use App\Services\UserService;
@@ -16,11 +17,27 @@ class OrderPackageFilters
 {
     protected $request;
     protected $queryBuilder;
-    protected $filters = ['logistic_number', 'status', 'received_at_start',
+    protected $filters = [
+        'logistic_number',
+        'status',
+        'received_at_start',
         'default_logistics',
         'is_issue',
         'sync_routes_flag',
-        'received_at_end', 'is_weighed', 'logistic', 'owner', 'sent_at_start', 'sent_at_end', 'is_exception', 'exception_type', 'default_date', 'has_transfer_status'];
+        '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',//订单备注
+    ];
 
     protected $orderIssueQuery;
 
@@ -60,12 +77,6 @@ class OrderPackageFilters
         }
     }
 
-    private function exception_type($exception_type)
-    {
-        $exception_types = array_filter(preg_split('/[,, ]+/is', $exception_type));
-
-        $this->queryBuilder->whereIn('exception_type', $exception_types);
-    }
 
     private function has_transfer_status($has_transfer_status)
     {
@@ -78,7 +89,8 @@ class OrderPackageFilters
 
     private function status($status)
     {
-        $this->queryBuilder->where('status', $status);
+        $statuses = array_filter(preg_split('/[,, ]+/is', $status));
+        $this->queryBuilder->whereIn('status', $statuses);
     }
 
     private function received_at_start($received_at_start)
@@ -124,11 +136,6 @@ class OrderPackageFilters
         $this->queryBuilder->where('sent_at', '<=', Carbon::parse($sent_at_end)->endOfDay());
     }
 
-    private function is_exception($is_exception)
-    {
-        $this->queryBuilder->where('exception', $is_exception);
-    }
-
     public function default_date()
     {
         $this->queryBuilder->where('sent_at', '>=', now()->startOfDay()->subDays(15))->where('sent_at', '<', now()->startOfDay()->addDay());
@@ -139,21 +146,70 @@ class OrderPackageFilters
         $this->queryBuilder->whereIn('order_id', function ($query) {
             $query->from('orders')
                 ->select('id')
-                ->whereNotIn('logistic_id', [13, 24, 25, 26, 27, 30, 31, 32, 33, 34, 60, 63, 65, 66, 68, 70, 102, 105, 107, 116,]);
+                ->whereNotIn('logistic_id', [13, 24, 25, 26, 27, 30, 31, 32, 33, 34, 60, 63, 65, 66, 68, 70, 102, 105, 107, 116, 10]);
         });
     }
 
     public function is_issue($is_issue)
     {
-        $this->queryBuilder->whereIn('order_id', function ($query) {
-            $query->from('orders')->select('id')->whereIn('id', function ($query) {
-                $query->from('order_issues')->select('order_id');
+        if ($is_issue === '是') {
+            $this->queryBuilder->whereIn('order_id', function ($query) {
+                $query->from('order_issues')->select('order_id')->whereNotNull('order_id');
             });
-        });
+        } else {
+            $this->queryBuilder->whereNotIn('order_id', function ($query) {
+                $query->from('order_issues')->select('order_id')->whereNotNull('order_id');
+            });
+        }
     }
 
     public function sync_routes_flag($sync_routes_flag)
     {
         $this->queryBuilder->where('sync_routes_flag', $sync_routes_flag === 'true');
     }
+
+    public function remark($remark)
+    {
+        $this->queryBuilder->whereIn('id', function ($query) use ($remark) {
+            $query->from('order_package_remarks')->select('order_package_id')->where('content', 'like', $remark);
+        });
+    }
+
+    public function is_new_rejecting($is_new_rejecting)
+    {
+        if ($is_new_rejecting === '有') {
+            $this->queryBuilder->whereIn('logistic_number', function ($query) {
+                $query->from('rejected_bills')->select('logistic_number_return')->where('logistic_number', '原单退回')->whereNotNull('logistic_number_return');
+            });
+        }
+        if ($is_new_rejecting === '无') {
+            $this->queryBuilder->whereNotIn('logistic_number', function ($query) {
+                $query->from('rejected_bills')->select('logistic_number_return')->where('logistic_number', '原单退回')->whereNotNull('logistic_number_return');
+            });
+        }
+    }
+
+    public function issue_type_name($issue_type_name)
+    {
+        $this->queryBuilder->whereIn('order_id', function ($query) use ($issue_type_name) {
+            $query->from('order_issues')->select('order_id')->where('order_issue_type_id', function ($query) use ($issue_type_name) {
+                $query->from('order_issue_types')->select('id')->where('name', $issue_type_name);
+            });
+        });
+    }
+
+    public function result_explain($result_explain)
+    {
+        $this->queryBuilder->whereIn('order_id', function ($query) use ($result_explain) {
+            $query->from('order_issues')->select('order_id')->where('result_explain', 'like', $result_explain);
+        });
+    }
+
+    public function order_notes($order_notes)
+    {
+        $ordernos = OracleDOCOrderHeader::query()->select('orderno')->where('notes', 'like', $order_notes)->pluck('orderno');
+        $this->queryBuilder->whereIn('order_id', function ($query) use ($ordernos) {
+            $query->from('orders')->select('order_id')->whereIn('code', $ordernos);
+        });
+    }
 }

+ 89 - 10
app/Filters/WorkOrderFilters.php

@@ -4,9 +4,15 @@
 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
 {
@@ -15,15 +21,28 @@ class WorkOrderFilters
     protected $request;
     protected $queryBuilder;
     protected $filters = [
-        'ids','creator','name','remake','created_at_start','created_at_end','review_at_start','review_at_end','reviewer','word_order_types','word_order_child_types','logistic'
+        'ids',
+        'creator',
+        'remake',
+        'created_at_start','created_at_end',
+        'review_at_start','review_at_end',
+        'reviewer',
+        'word_order_types',
+        'word_order_child_types',
+        'logistic',
+        'is_review',
+        'logistic_number',
+        'is_issue_order',
+        'order_issue_type',
+        'grad',
+        'owner'
     ];
     protected $array_filter;
-    protected $params = [
-        'ids','creator','name','remake','created_at_start','created_at_end','review_at_start','review_at_end','reviewer','word_order_types','word_order_child_types','logistic'
-    ];
+    protected $params = [];
 
     protected $workOrderTypeQuery;
     protected $orderQuery;
+    protected $orderPackageQuery;
 
     public function __construct(Request $request)
     {
@@ -49,16 +68,36 @@ class WorkOrderFilters
     {
         if(isset($this->params['data']))
             $this->id(explode(',',$this->params['data']));
+
+        if (!isset($this->params['owner'])){
+            $owners = app(OwnerService::class)->getAuthorizedOwners();
+            $this->getOrderQuery()->whereIn('owner_id',$owners->map(function($item){
+                return $item->id;
+            }));
+        }
     }
 
     public function beforeApply()
     {
+        if ($this->orderPackageQuery){
+            $this->getOrderQuery()->whereIn('id',$this->orderPackageQuery);
+        }
+
         if ($this->orderQuery) {
             $this->queryBuilder->whereIn('order_id',$this->getOrderQuery());
         }
+
+        // 审核 默认为 待审核
+        if (isset($this->params['is_review'])){
+            $this->queryBuilder->where('status','2');
+            $this->queryBuilder->whereHas('orderIssue');
+        } else {
+            $work_order_query = WorkOrder::query()->select('id')->where('status','2')->whereHas('orderIssue');
+            $this->queryBuilder->whereNotIn('id',$work_order_query);
+        }
     }
 
-    public function getOrderQuery()
+    public function getOrderQuery(): Builder
     {
         if (!$this->orderQuery){
             $this->orderQuery = Order::query()->select('id');
@@ -66,6 +105,14 @@ class WorkOrderFilters
         return $this->orderQuery;
     }
 
+    public function getOrderPackageQuery(): Builder
+    {
+        if (!$this->orderPackageQuery){
+            $this->orderPackageQuery = OrderPackage::query()->select('order_id');
+        }
+        return $this->orderPackageQuery;
+    }
+
     public function id($id)
     {
         if(is_array($id))$this->queryBuilder->whereIn('work_orders.id',$id);
@@ -93,12 +140,10 @@ class WorkOrderFilters
         $this->queryBuilder->where('work_orders.review_at','<=',$review_at_end);
     }
     // 创建人
-    public function creator($id)
+    public function creator($creator)
     {
-        if (is_array($id))
-            $this->queryBuilder->whereIn('work_orders.creator_id',$id);
-        else
-            $this->queryBuilder->where('work_orders.creator_id',$id);
+        $userQuery = User::query()->select('id')->where('name','like',"%{$creator}%");;
+        $this->queryBuilder->whereIn('creator_id',$userQuery);
     }
     // 审核人
     public function reviewer($id)
@@ -119,10 +164,44 @@ class WorkOrderFilters
         else $this->workOrderTypeQuery->where('id',$word_order_types);
     }
 
+    public function order_issue_type($order_issue_type)
+    {
+        $this->queryBuilder->where('order_issue_type_id',$order_issue_type);
+    }
 
+    // 快递单号
+    public function logistic_number($logistic_number)
+    {
+        $this->searchWay($this->getOrderPackageQuery(),$logistic_number,'order_packages.logistic_number');
+    }
+
+    // 对应问题件
+    public function is_issue_order($is_issue_order)
+    {
+        $orderIssueQuery = OrderIssue::query()->select('order_id')->whereIn('order_id',WorkOrder::query()->select('order_id'));
+        if($is_issue_order == 'true'){
+            $this->queryBuilder->whereIn('order_id',$orderIssueQuery);
+        } else {
+            $this->queryBuilder->whereNotIn('order_id',$orderIssueQuery);
+        }
+    }
+    // 承运商
     public function logistic($logistic)
     {
         $orderQuery = $this->getOrderQuery()->whereIn('id',WorkOrder::query()->select('order_id'));
         $this->searchWay($orderQuery,$logistic,'logistic_id');
     }
+
+    public function grad($grad)
+    {
+        $this->queryBuilder->where('grad',$grad);
+    }
+
+    // 货主
+    public function owner($owner)
+    {
+        $this->searchWay($this->queryBuilder,$owner,'work_orders.owner_id');
+    }
+
+
 }

+ 87 - 0
app/Http/ApiControllers/LoginController.php

@@ -0,0 +1,87 @@
+<?php
+
+
+namespace App\Http\ApiControllers;
+
+
+use Illuminate\Foundation\Auth\User;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Hash;
+
+class LoginController
+{
+    /**
+     * @api {post} /login 登录接口
+     * @apiName login
+     * @apiGroup User
+     *
+     * @apiParam {string} username 用户名
+     * @apiParam {string} password 用户密码,需要base64加密
+     *
+     * @apiSuccess {string} message 响应描述
+     * @apiSuccess {int} status_code HTTP响应码
+     * @apiSuccess {string} data.token 认证token
+     *
+     * @apiSuccessExample {json} Success-Response:
+     *     HTTP/1.1 200 OK
+     *     {
+     *       "message": "请求成功",
+     *       "status_code": "200"
+     *       "data":{
+     *             "toke":"token"
+     *        }
+     *     }
+     */
+    public function login(Request $request):JsonResponse
+    {
+        $userName = $request->get('username','');
+        $password = $request->get('password','');
+        $user = User::query()->where("name",$userName)->first();
+        $response = [
+            'message' => '请求成功',
+            'status_code' => 200,
+        ];
+        //验证用户登录
+        if (!$user || !Hash::check(base64_decode($password),$user->password)){
+            $response["message"] = "用户名或密码错误";
+            $response["status_code"] = 401;
+            return response()->json($response);
+        }
+
+        //获取公私钥
+        try {
+            $privateKey = file_get_contents(base_path().'/private.pem');
+        }catch (\Exception $e){
+            $response["status_code"] = 410;
+            if (strpos($e->getMessage(),"No such file or directory")!==false)$response["message"] = "服务器异常,资源丢失";
+            else $response["message"] = "访问某些资源失败";
+            return response()->json($response);
+        }
+
+        try {
+            $response["data"] = ["token"=>app("UserService")->getJWTToken($user,$privateKey)];
+            app("UserService")->setOrRefreshCache($user);
+            return response()->json($response);
+        }catch (\Exception $e){
+            $response["status_code"] = 409;
+            $response["message"] = "资源异常,无法反馈";
+            return response()->json($response);
+        }
+    }
+
+    public function test()
+    {
+        return response()->json([
+            "message" => "登陆成功",
+            "status_code"=>200,
+            "data"=>[
+                "param" => \request("test"),
+                "user" => Auth::id(),
+            ],
+        ]);
+    }
+
+
+}

+ 12 - 1
app/Http/Controllers/Auth/RegisterController.php

@@ -79,7 +79,6 @@ class RegisterController extends Controller
     {
         $headTo=$request->input('headTo')??'';
         $this->validator($request->all())->validate();
-
         event(new Registered($user = $this->create($request->all())));
         $phone=$request->input('phone');
         if ($phone) UserDetail::query()->create([
@@ -109,6 +108,18 @@ class RegisterController extends Controller
         if ($userWorkgroupId){
             $user->userWorkgroups()->sync([$userWorkgroupId]);
         }
+
+        //工作组
+        $work_id = [];
+        $treeData = $request->input('treeData')??[];
+        foreach ($treeData as $v){
+            if (strrpos($v,'g') != 'FALSE') array_push($work_id, mb_substr($v,1));
+        }
+        if ($work_id)$user->workGroups()->sync($work_id);
+        //项目组
+        $owners = $request->input('ownerGroup')??'';
+        if ($owners)$user->ownerGroups()->sync($owners);
+
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),$user['id']);
         if($headTo){return redirect(url($headTo))->with('successTip',"录入用户 {$user->name} 成功");}
         return $this->registered($request, $user)

+ 13 - 11
app/Http/Controllers/ControlPanelController.php

@@ -155,12 +155,11 @@ class ControlPanelController extends Controller
             foreach (CarbonPeriod::create($start,$end) as $date){
                 /** @var $date Carbon */
                 $str = $date->format("Y-m-d");
-                if (strtotime($str) <= strtotime(now())){
-                    $arr = $this->getTargetData($str, $owner);
-                    if ($arr) {
-                        $data[] = $arr;
-                        $title[] = $str;
-                    }
+                if (strtotime($str) >= strtotime(date("Y-m-d"))) continue;
+                $arr = $this->getTargetData($str, $owner);
+                if ($arr) {
+                    $data[] = $arr;
+                    $title[] = $str;
                 }
             }
             $start = date('Y-m-d', strtotime($start));
@@ -172,12 +171,15 @@ class ControlPanelController extends Controller
 
         //data数据处理
         $real_data = [];
-        foreach ($machines as $v){
-            $temp = [$v['name']];
-            foreach ($data as $val){
-                array_push($temp, array_column($val, $v['id'])? array_sum( array_column($val, $v['id'])) : 0);
+        foreach ($machines as $v) {
+            $temp = [];
+            foreach ($data as $val) {
+                array_push($temp, array_column($val, $v['id']) ? array_sum(array_column($val, $v['id'])) : 0);
+            }
+            if (array_sum($temp) > 0) {
+                array_unshift($temp, $v['name']);
+                array_push($real_data, $temp);
             }
-            array_push($real_data,$temp);
         }
         array_unshift($title, 'product');
         array_unshift($real_data, $title);

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

@@ -114,7 +114,7 @@ class HandInStorageController extends Controller
             if ($result===1)$this->error('需要维护产品档案');
             if ($result===2)$this->error('需要维护该产品档案中的重量体积');
         }
-        if ($handInStorageService->checkForwardingLoc($info)===1)$this->error('请维护拣货位');
+        if ($info['customerid']=='JIANSHANG'&&$handInStorageService->checkForwardingLoc($info)===1)$this->error('请维护拣货位');
         try {
             $result = $handInStorageService->fluxHandIn($info);
             if ($result){
@@ -191,10 +191,22 @@ class HandInStorageController extends Controller
             if ($result===false) $this->error("上架失败");
             if ($result===1)$this->error("拣货区找到效期更新的同样货品,不能上架至存储区");
         } catch (\Exception $e) {
+            $this->error($e->getMessage());
             app('LogService')->log(__METHOD__,'error_'.__FUNCTION__,json_encode($info).'|catch:'.$e->getMessage());
         }
     }
 
+    public function getInventoryInfos(Request $request)
+    {
+        $this->gate("入库管理-手持入库-库存查询");
+        $param=$request->input('location');
+        /** @var HandInStorageService $handInStorageService  */
+        $handInStorageService=app('HandInStorageService');
+        $invs=$handInStorageService->getInventoryInfos($param);
+        if (count($invs)>0)$this->success($invs);
+        else $this->error('未查询到库存信息');
+    }
+
 
 
 

+ 3 - 5
app/Http/Controllers/InventoryAccountController.php

@@ -40,9 +40,7 @@ class InventoryAccountController extends Controller
     //创建盘点任务
     public function createStockInventoryMission(Request $request)
     {
-        if (!Gate::allows("库存管理-盘点")) {
-            return redirect(url('/'));
-        }
+        if (!Gate::allows("库存管理-盘点")) {return ['success' => false ,'data' => '没有对应权限'];}
 //        $date_start=$request->input('formData.date_start');
 //        $date_end=$request->input('formData.date_end');
 //        $ownerId=$request->input('formData.owner_id')[0];
@@ -51,8 +49,8 @@ class InventoryAccountController extends Controller
         $ownerId = $request->input('owner_id');
         $location = $request->input('location');
         $barcode = $request->input('barcode');
-        $inventoryAccount = app('inventoryAccountService')->createMission($date_start, $date_end, $ownerId, $location, $barcode);
-        $inventoryAccount = InventoryAccount::with('owner')->find($inventoryAccount->id);
+        $inventory = app('inventoryAccountService')->createMission($date_start, $date_end, $ownerId, $location, $barcode);
+        $inventoryAccount = InventoryAccount::with('owner')->find($inventory->id);
         if (is_null($inventoryAccount)) return ['success' => false, 'data' => '参数错误!'];
         return ['success' => true, 'data' => $inventoryAccount];
     }

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

@@ -32,7 +32,7 @@ class LaborCompanyController extends Controller
         $this->validatorCreate($request->all())->validate();
         $laborCompany=new LaborCompany($request->all());
         $laborCompany->save();
-        app('LaborCompanyService')->createAuthority($laborCompany);//创建劳务所创建对应权限
+        app('LaborCompanyService')->createRole($laborCompany);
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
         return redirect('maintenance/laborCompany/create')->with('successTip',"成功录入劳务所“{$request->input('name')}”");
     }
@@ -84,7 +84,7 @@ class LaborCompanyController extends Controller
         $this->validatorUpdate($request->all())->validate();
         $laborCompany->fill($request->all());
         $laborCompany->update();
-        app('LaborCompanyService')->updateAuthority($laborCompany);
+        app('LaborCompanyService')->updateRole($laborCompany);
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
         return redirect('maintenance/laborCompany/')->with('successTip',"成功修改劳务所“{$laborCompany['name']}”!");
     }

+ 1 - 0
app/Http/Controllers/LaborReportController.php

@@ -141,6 +141,7 @@ class LaborReportController extends Controller
         if(!Gate::allows('人事管理-组长审核')){ return ["success"=>false,"data"=>"您无此权限操作!"];  }
         $id=$request->input('id');
         $laborReport=LaborReport::find($id);
+        if (!$laborReport)return ["success"=>false,"data"=>"数据发生改变,无法操作!"];
         $laborReport->group_user_id=Auth::user()['id'];
         $laborReport->verify_at=date('Y-m-d H:i:s');
         $laborReport->update();

+ 12 - 17
app/Http/Controllers/MeasureMonitorController.php

@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
 
 use App\MeasuringMachine;
 use App\OrderPackage;
+use App\Services\MeasureMonitorService;
 use Illuminate\Http\Request;
 require_once '../app/library/baidu-api-speech/AipSpeech.php';
 class MeasureMonitorController extends Controller
@@ -36,24 +37,18 @@ class MeasureMonitorController extends Controller
         return '';
     }
 
-
-    public function speech(Request $request){
-        $logistic=$request->input('logistic');
-        if (!$logistic)$logistic='空';
-        if (file_exists("storage/".$logistic.'.mp3')){
-            return "/storage/".$logistic.'.mp3';
+    /** 获取快递面单的语音播报 */
+    public function speech(Request $request,MeasureMonitorService $service): array
+    {
+        if (app('WorkOrderService')->isIntercept($request['logistic_number'])){
+            return $service->getMp3Audio('拦截订单');
         }
-        $client=new \AipSpeech(config('api.baidu.speech.APP_ID'),config('api.baidu.speech.API_KEY'),config('api.baidu.speech.SECRET_KEY'));
-        $client->setConnectionTimeoutInMillis('180000');
-        $client->setSocketTimeoutInMillis('180000');
-
-        $result = $client->synthesis($logistic, 'zh', 1, array(
-            'vol' => 15,
-        ));
-        // 识别正确返回语音二进制 错误则返回json 参照下面错误码
-        if(!is_array($result)){
-            file_put_contents('storage/'.$logistic.'.mp3', $result);
+        if ( app('OrderIssueService')->isExists($request['logistic_number'])){
+            return $service->getMp3Audio('拦截订单');
         }
-        return "/storage/".$logistic.'.mp3';
+        return $service->getMp3Audio($request->input('logistic'));
+
     }
+
+
 }

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

@@ -21,7 +21,6 @@ use PhpParser\Node\Stmt\DeclareDeclare;
 class OrderController extends Controller
 {
     public function delivering(OrderDelivering $request){
-        //if(!Gate::allows('订单管理-查询')){ return view('order/index');  }
         /** @var OrderService $orderService */
         $orderService = app('OrderService');
         $request = $request->input();
@@ -41,13 +40,13 @@ class OrderController extends Controller
         $result = $orderService->paginate($request);
         $picktotraceids = $result['picktotraceids'];
         $orders = $result['orders'];
-        $orderIssueNos =  $orderService->返回有问题件的订单号($orders);
+        $orderService->tagOrderByOrderIssue($orders);
         $commodities = $result['commodities'];
         $customers=app('OracleBasCustomerService')->getCustomers($codes);
         $page = $request["page"] ?? 1;
         $codes=DB::connection('oracle')->table('BAS_CODES')->select('code','codename_c')->where('codeid','SO_STS')->orderBy('code','asc')->get();
         $orderIssueType = OrderIssueType::all();
-        return view('order/index/delivering',compact('orders','customers','request','codes','commodities','page','picktotraceids','orderIssueType','orderIssueNos','logistics'));
+        return view('order/index/delivering',compact('orders','customers','request','codes','commodities','page','picktotraceids','orderIssueType','logistics'));
     }
 
     //导出

+ 16 - 8
app/Http/Controllers/OrderIssueProcessLogController.php

@@ -2,9 +2,9 @@
 
 namespace App\Http\Controllers;
 
+use App\Exceptions\Exception;
 use App\OrderIssue;
 use App\OrderIssueProcessLog;
-use App\Services\LogService;
 use App\Services\OrderIssueProcessLogService;
 use App\User;
 use Illuminate\Http\Request;
@@ -19,7 +19,7 @@ class OrderIssueProcessLogController extends Controller
      * @param Request $request
      * @return array
      */
-    public function apiStore(Request $request)
+    public function apiStore(Request $request): array
     {
         if (!Gate::allows('订单管理-问题件-编辑')) {
             return ['success' => false, 'fail_info' => '没有对应的权限'];
@@ -29,16 +29,13 @@ class OrderIssueProcessLogController extends Controller
                 $log = OrderIssueProcessLog::query()->create([
                     'order_issue_id' => $request->input('id'),
                     'content' => $request->input('content'),
+                    'tag' => $request->input('tag'),
                     'user_id' => Auth::user()['id'],
                     'type' => '处理',
                 ]);
-                if ($log) {
-                    $log->user = $log->hasOne(User::class, 'id', 'user_id')->first();
-                }
-                app('LogService')->log(__METHOD__, __FUNCTION__, json_encode($request->getContent()));
+                $log->loadMissing('user');
                 return ['success' =>true,'data' =>$log ];
-            } catch (\Exception $e) {
-                app('LogService')->log(__METHOD__, __FUNCTION__, json_encode($request->getContent()) .'||'.$e->getMessage().'||'.$e->getTraceAsString());
+            } catch (Exception $e) {
                 return ['success' => false, 'fail_info' => $e->getMessage()];
             }
         } else {
@@ -96,4 +93,15 @@ class OrderIssueProcessLogController extends Controller
         }
     }
 
+    // 标记处理记录
+    public function tagApi(Request $request): array
+    {
+        if (Gate::denies('订单管理-问题件-编辑'))
+            return ['success' => false, 'fail_info' => '没有对应的权限'];
+
+        OrderIssueProcessLog::query()->where('id',$request['id'])->update(['tag'=>1]);
+
+        return ['success' => true];
+    }
+
 }

+ 23 - 1
app/Http/Controllers/OrderPackageController.php

@@ -3,6 +3,7 @@
 namespace App\Http\Controllers;
 
 use App\OrderPackage;
+use App\OrderPackageRemark;
 use Illuminate\Http\Request;
 
 class OrderPackageController extends Controller
@@ -31,8 +32,29 @@ class OrderPackageController extends Controller
         $orderPackage = OrderPackage::query()->find($request->input('orderPackageId'));
 
 
-        $orderPackage->orderPackageRemarks()->where('id',$request->remarkId)->delete();
+        $orderPackage->orderPackageRemarks()->where('id', $request->remarkId)->delete();
         return ['success' => true, 'data' => $orderPackage->orderPackageRemarks()->with('user')->orderByDesc('created_at')->get()];
     }
 
+    public function benchRemark(Request $request)
+    {
+        $orderPackageIds =
+            OrderPackage::query()
+                ->select('id')
+                ->whereIn('logistic_number', $request->logistic_numbers)
+                ->pluck('id');
+
+        $createDate = [];
+        foreach ($orderPackageIds as $order_package_id) {
+            $createDate[] = [
+                'user_id' => auth()->id(),
+                'order_package_id' => $order_package_id,
+                'content' => $request->remark,
+                'created_at' => now(),
+            ];
+        }
+        OrderPackageRemark::query()->insert($createDate);
+        return ['success' => true, 'data' => []];
+    }
+
 }

+ 14 - 0
app/Http/Controllers/OrderPackageExpressBillPrintRecordController.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\OrderPackageExpressBillPrintRecordService;
+
+class OrderPackageExpressBillPrintRecordController extends Controller
+{
+    public function updateRecordApi($logistic_number,OrderPackageExpressBillPrintRecordService  $service,$task_id): array
+    {
+        return $service->expressBillPrintRecord($logistic_number,$task_id);
+    }
+
+}

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

@@ -6,6 +6,7 @@ use App\Authority;
 use App\Components\AsyncResponse;
 use App\Events\CustomerStored;
 use App\Owner;
+use App\OwnerGroup;
 use Exception;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;

+ 84 - 0
app/Http/Controllers/OwnerGroupController.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\Facades\Validator;
+
+class OwnerGroupController
+{
+    public function index(Request $request)
+    {
+        if (!Gate::allows('货主组别-查询')) {
+            return redirect('denied');
+        }
+        $params = $request->all();
+        $groups = app('OwnerGroupService')->paginate($params);
+        return response()->view("maintenance.OwnerGroup.index", compact("groups"));
+    }
+
+    public function create()
+    {
+        if (!Gate::allows('货主组别-录入')) {
+            return redirect('denied');
+        }
+        return response()->view("maintenance.ownerGroup.create");
+    }
+
+    public function store(Request $request)
+    {
+        if (!Gate::allows('货主组别-录入')) {
+            return redirect('denied');
+        }
+        $this->validator($request->input())->validate();
+        app('OwnerGroupService')->create([
+            "name" => $request->input("name"),
+        ]);
+        return response()->redirectTo("maintenance/ownerGroup")->with("successTip","成功创建货主组别“".$request->input("name")."”");
+    }
+
+    public function edit($id)
+    {
+        if (!Gate::allows('货主组别-编辑')) {
+            return redirect('denied');
+        }
+        $group = app('OwnerGroupService')->find($id);
+        return response()->view('maintenance.ownerGroup.create', compact("group"));
+    }
+
+    public function update(Request $request, $id)
+    {
+        if(!Gate::allows('货主组别-编辑')){ return redirect('denied');  }
+        $this->validator($request->input(),$id)->validate();
+        $result = app('OwnerGroupService')->update(["id"=>$id],[
+            "name"=>$request->input("name"),
+        ]);
+        if ($result == 1){
+            return response()->redirectTo("maintenance/ownerGroup")->with("successTip","成功修改基础设置-货主组别“".$request->input("name")."”的信息");
+        }
+        return response()->view("exception.default",["code"=>"509"]);
+    }
+
+    public function destroy($id)
+    {
+        if(!Gate::allows('货主组别-删除')){ return ["success"=>false,"data"=>"无权操作!"];  }
+        $result = app('OwnerGroupService')->destroy($id);
+        if ($result == 1)return ["success"=>true];
+        return ["success"=>false,"data"=>"删除了“".$result."”行"];
+    }
+
+    private function validator(array $params, $id = null)
+    {
+        return Validator::make($params,[
+            'name'=>['required',$id?"unique:owner_groups,name,$id":'unique:owner_groups,name','max:20'],
+        ],[
+            'required'=>':attribute 为必填项',
+            'max'=>':attribute 字符过多或输入值过大',
+            'unique'=>':attribute 已存在',
+        ],[
+            'name'=>'货主组别名称',
+        ]);
+    }
+
+}

+ 77 - 46
app/Http/Controllers/PackageLogisticController.php

@@ -11,6 +11,7 @@ use App\Owner;
 use App\Services\common\ExportService;
 use App\Services\UserService;
 use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
 
 class PackageLogisticController extends Controller
 {
@@ -30,16 +31,22 @@ class PackageLogisticController extends Controller
         $paginateParams = $request->input();
         $orderPackages = OrderPackage::query()
             ->filter($filters)
-            ->with(['order.logistic',
-                'orderPackageRemarks'=>function ($query){
+            ->with([
+                'order.logistic',
+                'order.batch:id,wms_type',
+                'order.OracleDOCOrderHeader:orderno,notes,WaveNo',
+                'rejectedBill' => function ($query) {
+                    $query->select('id', 'logistic_number', 'logistic_number_return')->where('logistic_number', '原单退回');
+                },
+                'orderPackageRemarks' => function ($query) {
                     $query->with('user')->orderByDesc('created_at');
                 },
                 'order.owner',
                 'order.issue' => function ($query) {
-                $query->with(['issueType', 'logs' => function ($query) {
-                    $query->with('user')->orderBy('created_at', 'DESC');
-                }]);
-            }])
+                    $query->with(['issueType', 'logs' => function ($query) {
+                        $query->with('user')->orderBy('created_at', 'DESC');
+                    }]);
+                }])
             ->orderByDesc('id')
             ->paginate($request->paginate ?? 50);
         $logistics = Logistic::all();
@@ -63,21 +70,11 @@ class PackageLogisticController extends Controller
 
     public function batchUpdate(Request $request)
     {
-        $data = [];
-        if (array_key_exists('exception_type', $request->all())) {
-            if ('无' == $request->input('exception_type')) {
-                $data['exception_type'] = $request->input('exception_type');
-                $data['exception'] = "否";
-            } else {
-                $data['exception_type'] = $request->input('exception_type');
-            }
-        } else if (array_key_exists('status', $request->all())) {
-            $data['status'] = $request->input('status');
-        }
-        $logistic_numbers = $request->input('logistic_numbers');
-        OrderPackage::query()->whereIn('logistic_number', $logistic_numbers)->update($data);
-        //更新统计数据
-        event(new UpdateOrderPackageExceptionListenerEvent($logistic_numbers));
+        OrderPackage::query()->whereIn('logistic_number', $request->input('logistic_numbers'))->update([
+            'status' => OrderPackage::switchStatus($request->input('status')),
+            //标记为手动更新
+            'is_manual_update' => true,
+        ]);
     }
 
     /**
@@ -90,12 +87,21 @@ class PackageLogisticController extends Controller
         $owner_ids = $userService->getPermittingOwnerIds(auth()->user());
         $query = OrderPackage::query()
             ->filter($filters)
-            ->whereIn('owner_id', $owner_ids)
-            ->with(['order.logistic', 'order.owner', 'order.issue' => function ($query) {
-                $query->with(['issueType', 'logs' => function ($query) {
-                    $query->with('user')->orderBy('created_at', 'DESC');
-                }]);
-            }]);
+            ->with([
+                'order.logistic',
+                'rejectedBill' => function ($query) {
+                    $query->select('id', 'logistic_number', 'logistic_number_return')->where('logistic_number', '原单退回');
+                },
+                'orderPackageRemarks' => function ($query) {
+                    $query->with('user')->orderByDesc('created_at');
+                },
+                'order.owner',
+                'order.issue' => function ($query) {
+                    $query->with(['issueType', 'logs' => function ($query) {
+                        $query->with('user')->orderBy('created_at', 'DESC');
+                    }]);
+                }])
+            ->orderByDesc('id');
         if ($request->exists('checkAllSign')) {
             $orderPackages = $query->orderByDesc('id')->get();
         } else {
@@ -103,7 +109,27 @@ class PackageLogisticController extends Controller
                 ->whereIn('logistic_number', explode(',', $request['data']))
                 ->orderByDesc('id')->get();
         }
-        $row = ["异常类型", "单号", "状态", "快递公司", "货主", "省份", "发出日期", "收货日期", "称重日期", "快递路由", "客服备注", "情况说明", "问题类别", "说明", "操作者", "时间",];
+        $row = [
+            '单号',
+            '状态',
+            '快递公司',
+            '货主',
+            '省份',
+            '发出日期',
+            '收货日期',
+            '称重日期',
+            '快递路由',
+            '退件状态',
+            '订单备注',
+            '客服备注',
+            '情况说明',
+            '问题类别',
+            '波次规则',
+            '波次号',
+            '说明',
+            '操作者',
+            '时间',
+        ];
         $json = [];
         foreach ($orderPackages as $orderPackage) {
             $transfer_status = "";
@@ -115,9 +141,9 @@ class PackageLogisticController extends Controller
                 }
             }
             $remark = "";
-            if (is_array($orderPackage->remark) && !empty($orderPackage->remark)) {
-                foreach ($orderPackage->remark as $remarkItem) {
-                    $remark = $remark . $remarkItem . ",\r\n";
+            if (!empty($orderPackage->orderPackageRemarks)) {
+                foreach ($orderPackage->orderPackageRemarks as $remarkItem) {
+                    $remark = $remark . $remarkItem->content . '-' . $remarkItem->user->name . '-' . $remarkItem->created_at . ",\r\n";
                 }
             }
             $logsContent = "";
@@ -131,23 +157,28 @@ class PackageLogisticController extends Controller
                 }
             }
             $data = [
-                $orderPackage->exception_type,
-                $orderPackage->logistic_number,
-                $orderPackage->status,
-                $orderPackage->order->logistic->name,
-                $orderPackage->order->owner->name,
-                $orderPackage->order->province,
-                $orderPackage->sent_at,
-                $orderPackage->received_at,
-                $orderPackage->weighed_at,
-                $transfer_status,
-                $remark,
-                $logsContent,
-                $users,
-                $logCreatedAt,
+                $orderPackage->logistic_number ?? '',//单号
+                $orderPackage->status ?? '',//状态
+                $orderPackage->order->logistic->name ?? '',//快递公司
+                $orderPackage->order->owner->name ?? '',//货主
+                $orderPackage->order->province ?? '',//省份
+                $orderPackage->sent_at ?? '',//发出日期
+                $orderPackage->received_at ?? '',//收货日期
+                $orderPackage->weighed_at ?? '',//称重日期
+                $transfer_status ?? '',//快递路由
+                empty($orderPackage->rejectedBill) ? '无' : '有',//退件状态
+                $orderPackage->order->OracleDOCOrderHeader->notes ?? '',//订单备注
+                $remark ?? '',//客服备注
+                $orderPackage->order->issue->result_explain ?? '',//情况说明
+                $orderPackage->order->issue->issueType->name ?? '',//问题类别
+                $orderPackage->order->batch->wms_type ?? '',//波次规则
+                $orderPackage->order->OracleDOCOrderHeader->waveno ?? '',//波次号
+                $logsContent ?? '',//说明
+                $users ?? '',//操作者
+                $logCreatedAt ?? '',//时间
             ];
             $json[] = $data;
         }
-        return app(ExportService::class)->json($row, $json, "包裹快递");
+        return Export::make($row, $json, "包裹快递");
     }
 }

+ 40 - 0
app/Http/Controllers/PrintController.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\AsyncResponse;
+use App\Services\DeliveryService;
+use App\Services\TerminalPrinterLogisticService;
+use Illuminate\Http\Request;
+
+class PrintController extends Controller
+{
+    //
+    use AsyncResponse;
+
+    public function index()
+    {
+        return view('maintenance.expressPrinting.print.template');
+    }
+
+    public function getPrintDataApi(Request $request): array
+    {
+        if (!$request->has('printStr')) return ['success' => false, 'message' => '为空'];
+        $results = app(DeliveryService::class)->getDelivery($request['printStr']);
+        // 匹配打印机
+        $results = app(TerminalPrinterLogisticService::class)->setPrinterName($results);
+
+        //
+        return ['success' => true, 'data' => $results];
+    }
+
+    public function uploadPrintDataApi(Request $request, DeliveryService $service): array
+    {
+        if (is_string($request['printData']))
+            $request['printData'] = json_decode($request['printData']);
+
+        $item = $service->customProcessing($request['printData']);
+        return ['success' => true, 'data' => $item];
+    }
+
+}

+ 3 - 49
app/Http/Controllers/PrintPartController.php

@@ -3,64 +3,18 @@
 namespace App\Http\Controllers;
 
 use App\Components\AsyncResponse;
-use App\Order;
-use App\PrintPart;
-use App\PrintTemplate;
 use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Http;
 
 class PrintPartController extends Controller
 {
     use AsyncResponse;
-    public function index(Request $request)
-    {
-        $printParts = PrintPart::query()->paginate($request['paginate'] ?? 50);
-        return view('/maintenance/expressPrinting/part/index',compact('printParts'));
-    }
 
     public function create(Request $request)
     {
-        return view('/maintenance/expressPrinting/part/create');
+        // 废弃
+        //$imgPrintPart = app(PrintPartService::class)->getImagePart();
+        //return view('maintenance.expressPrinting.part.create',compact('imgPrintPart'));
     }
 
-    public function storeApi(Request $request): \Illuminate\Http\RedirectResponse
-    {
-        PrintPart::query()->create($request->all());
-        $this->success('添加成功');
-    }
-
-    public function destroyApi(Request $request)
-    {
-        $printPart = PrintPart::query()->find($request['id']);
-        $printPart->delete();
-        $this->success('删除成功');
-    }
 
-    public function print(Request $request)
-    {
-        $template = PrintTemplate::query()->where('name','test-快递单号打印')->first();
-        $items = Order::query()->whereIn('code',["SO190628000378","SO190628000347"])->with('packages')->get();
-        return view("maintenance.expressPrinting.print.index",compact("template",'items'));
-    }
-
-    public function printTemplateApi(Request $request)
-    {
-        $file = $request->file("blob");
-        $content = $file->getContent();
-        $content = base64_encode($content);
-        $files = $request->file("blobs");
-
-        $content = [
-            "type" => "print",
-            "aliasName"=>"admin",
-            "printerName"=>"admin123",
-            "content" => $content
-        ];
-        if(!$files)return Http::post("http://127.0.0.1:3000",$content);
-        $contents = [];
-        foreach ($files as $item) {
-            $contents[] = base64_encode($item->getContent());
-        }
-        return Http::post("http://127.0.0.1:3000",['file'=>$content,'files'=>$contents]);
-    }
 }

+ 64 - 0
app/Http/Controllers/PrintPartImageController.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\PrintPartImage;
+use App\Services\PrintPartImageService;
+use App\UploadFile;
+use Illuminate\Http\Request;
+
+class PrintPartImageController extends Controller
+{
+
+    public function index(Request $request)
+    {
+        $printPartImages = PrintPartImage::query()->with('file')->paginate($request['paginate'] ?? 50);
+        return view('maintenance.expressPrinting.image.index', compact('printPartImages'));
+    }
+
+    /**
+     * 保存图片
+     * @param Request $request
+     * @param PrintPartImageService $service
+     * @return array
+     */
+    public function saveFileApi(Request $request, PrintPartImageService $service): array
+    {
+        $file = $request->file('file');
+        /** @var PrintPartImage $printPartImage */
+        $printPartImage = PrintPartImage::query()->with('file')->where('name', $request['name'])->first();
+        if (!$printPartImage) $printPartImage = PrintPartImage::query()->firstOrCreate(['name' => $request['name']]);
+        if ($printPartImage['file']) return ['success' => false, 'message' => '该需求已有描述图片'];
+        return $service->saveFile($printPartImage, $file);
+    }
+
+    /**
+     * 修改图片
+     * @param Request $request
+     * @param PrintPartImageService $service
+     * @return array
+     */
+    public function updateFileApi(Request $request, PrintPartImageService $service): array
+    {
+        $file = $request->file('file');
+        /** @var PrintPartImage $printPartImage */
+        $printPartImage = PrintPartImage::query()->with('file')->where('name', $request['name'])->first();
+        return $service->updateFile($printPartImage, $file);
+    }
+
+    /**
+     * 删除图片
+     * @param $id
+     * @param PrintPartImageService $service
+     * @return bool[]
+     * @throws \Exception
+     */
+    public function destroyApi($id, PrintPartImageService $service): array
+    {
+        $item = PrintPartImage::query()->with('file')->find($id);
+        UploadFile::query()->where(['table_name' => (new PrintPartImage())->getTable(), 'table_id' => $item['id']])->delete();
+        $item->delete();
+        return ['success' => true];
+    }
+
+}

+ 46 - 15
app/Http/Controllers/PrintTemplateController.php

@@ -3,47 +3,78 @@
 namespace App\Http\Controllers;
 
 use App\Components\AsyncResponse;
-use App\PrintPart;
+use App\Logistic;
+use App\Owner;
+use App\PrintPartImage;
 use App\PrintTemplate;
+use App\Services\PrintTemplateService;
 use Illuminate\Http\Request;
 
 class PrintTemplateController extends Controller
 {
     use AsyncResponse;
+
     public function index(Request $request)
     {
-        $templates = PrintTemplate::all();
-        return view('/maintenance/expressPrinting/template/index',compact('templates'));
+        $templates = PrintTemplate::query()->with(['ownerLogisticPrintTemplate' => function ($query) {
+            $query->with(['owner', 'logistic']);
+        }])->paginate($request['paginate'] ?? 50);
+        $owners = Owner::query()->get();
+        $logistics = Logistic::query()->get();
+        return view('maintenance.expressPrinting.template.index', compact('templates', 'owners', 'logistics'));
     }
 
-    public function create(Request $request)
+    public function create(PrintTemplateService $service)
     {
-        $printParts = PrintPart::all();
-        return view('/maintenance/expressPrinting/template/create',compact('printParts'));
+        $printParts = $service->getParts();
+        $printPartImages = PrintPartImage::query()->with('file')->get();
+        return view('maintenance.expressPrinting.template.create', compact('printParts', 'printPartImages'));
     }
 
+    public function edit($id, PrintTemplateService $service)
+    {
+        $template = PrintTemplate::query()->find($id);
+        $printParts = $service->getParts();
+        $printPartImages = PrintPartImage::query()->with('file')->get();
+        return view('maintenance.expressPrinting.template.edit', compact('template', 'printParts', 'printPartImages'));
+    }
 
     public function storeApi(Request $request)
     {
-        $data = [
-            'name' =>$request['name'],
-            'value'=>json_encode($request['value'])
-        ];
-        $printTemplate = PrintTemplate::query()->create($data);
+        $printTemplate = PrintTemplate::query()->create([
+            'name' => $request['name'],
+            'value' => $request['value']
+        ]);
         $this->success(['data' => $printTemplate]);
     }
 
-    public function updateApi(Request $request)
+    public function updateApi(Request $request): array
     {
-
+        $print_template = PrintTemplate::query()->find($request['id']);
+        $print_template->update([
+                'name' => $request['name'],
+                'value' => $request['value']]
+        );
+        return ['success' => true, 'data' => $print_template];
     }
 
-    public function destroyApi(Request $request)
+    public function destroyApi($id)
     {
-        $printTemplate = PrintTemplate::query()->find($request['id']);
+        $printTemplate = PrintTemplate::query()->find($id);
         $printTemplate->delete();
         $this->success('删除成功');
     }
 
+    // 保存 打印模板和 货主 承运商 之间的关系
+    public function saveRelationApi(Request $request, PrintTemplateService $service): array
+    {
+        $relations = $request['relations'];
+        $service->saveRelation($relations);
+        $item = PrintTemplate::query()->with(['ownerLogisticPrintTemplate' => function ($query) {
+            $query->with(['owner', 'logistic']);
+        }])->where('id',$request['template_id'])->first();
+        return ['success' => true, 'data' => $item];
+    }
+
 
 }

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

@@ -14,7 +14,6 @@ use App\ProcessesContent;
 use App\ProcessMethod;
 use App\ProcessStatistic;
 use App\Services\OwnerService;
-use App\Services\ProcessService;
 use App\Sign;
 use App\Tutorial;
 use App\User;
@@ -22,14 +21,15 @@ use App\UserDetail;
 use App\UserDutyCheck;
 use App\UserLabor;
 use Carbon\Carbon;
-use Exception;
+use Illuminate\Contracts\Foundation\Application;
+use Illuminate\Contracts\View\Factory;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
-use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Validator;
+use Illuminate\View\View;
 use Oursdreams\Export\Export;
 use Ramsey\Uuid\Uuid;
 
@@ -39,11 +39,10 @@ class ProcessController extends Controller
      * Display a listing of the resource.
      * @param Request $request
      * @param OwnerService $ownerService
-     * @return void
+     * @return Application|Factory|View
      */
     public function index(Request $request,OwnerService $ownerService)
     {
-        if(!Gate::allows('二次加工管理-查询')){ return redirect(url('/'));  }
         $paginateParams = $request->input();
         $processes = app('ProcessService')->paginate($paginateParams);
         $owners=$ownerService->getIntersectPermitting();
@@ -201,9 +200,8 @@ class ProcessController extends Controller
     public function accomplish(Request $request){
         if(!Gate::allows('二次加工管理-交接完成')){ return ['success'=>false,'data'=>'您无权进行该操作!'];  }
         $process=Process::with('processDailies')->find($request->id);
-        if (!$process)return ['success'=>false];
+        if (!$process || $process->status == '交接完成')return ['success'=>false];
         $result=$this->statistic($process);
-//        if (!$result['success'])return $result;
         $process->update(['status'=>'交接完成']);
         $process->createOperatorLog('交接完成');
         $processStatistic=$result['data'];

+ 3 - 2
app/Http/Controllers/RejectedBillController.php

@@ -157,11 +157,12 @@ class RejectedBillController extends Controller
         ){
             $mobileShouldBeRequired = 'nullable';
         }}
-        if($data['id_owner']=='4'){
+        if(isset($data['id_owner']) && $data['id_owner']=='4'){
             $mobileShouldBeRequired = 'nullable';
         }
         $mobileDigits = '';
         if($data['mobile_sender']&&$data['mobile_sender'][0]=='1'){
+            $data['mobile_sender'] = str_replace('*','0',$data['mobile_sender']);
             $mobileDigits = 'digits:11';
         }
         return Validator::make($data, [
@@ -175,7 +176,7 @@ class RejectedBillController extends Controller
             'fee_collected' => ['nullable','between:0,99999','numeric'],
             'is_loaded' => ['nullable'],
         ],[
-            'mobile_sender.digits'=>'如果是手机则必须为11位',
+            'mobile_sender.digits'=>'如果是手机则必须为11位且不可包含非法符号',
         ],[
             'id_owner'=>'客户名称',
             'order_number'=>'订单号',

+ 1 - 0
app/Http/Controllers/RejectedBillItemController.php

@@ -364,6 +364,7 @@ class RejectedBillItemController extends Controller
         $rejectedBillItem->forceDelete();
         /** @var RejectedBill $rejectedBill */
         $rejectedBill = RejectedBill::query()->where('id',$rejectedBillItem->id_rejected_bill)->first();
+        if(!$rejectedBill)return ['success'=>'false','id'=>$request->input('id')];
         $rejectedBill->syncOrderIssue(); // 同步问题件 修改问题件退货状态
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($rejectedBillItem),Auth::user()['id']);
         return ['success'=>'true','id'=>$request->input('id')];

+ 11 - 1
app/Http/Controllers/RequirementController.php

@@ -9,6 +9,7 @@ use App\Role;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Gate;
 
 class RequirementController extends Controller
 {
@@ -35,7 +36,10 @@ class RequirementController extends Controller
     {
         $requirement->fill($request->all());
         $requirement->user_id = Auth::id();
-        $requirement->status = '待接收';
+        $status = null;
+        if (Gate::allows('需求发布-新建-业务部门新建')) $status ='待审核';
+        if (Gate::allows('需求发布-新建-直接发布')) $status ='待接收';
+        $requirement->status = $status;
         $requirement->save();
         return redirect()->route('requirements.index', $requirement->id)->with('success', '需求创建成功!');
     }
@@ -129,4 +133,10 @@ class RequirementController extends Controller
         $requirement->save();
         return redirect()->route('requirements.show', $requirement->id)->with('success', '再次申请验收流程完成');
     }
+
+    public function status(Requirement $requirement,Request $request)
+    {
+        $requirement->update($request->all());
+        return redirect()->route('requirements.show', $requirement->id)->with('success', "状态更新为 {$request->status}成功!");
+    }
 }

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

@@ -52,12 +52,12 @@ class SettlementBillExpressFeeDetailController extends Controller implements Set
 
     public function export(Request $request)
     {
-        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->owner_id, $request->year, $request->month);
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month,$request->owner_id  );
         $query = $this->service->getSql($owner_id, $counting_month);
         if (!$request->exists('checkAllSign')) {
             $query->whereIn('id', explode(',', $request['data']));
         }
-        $details = $this->service->buildDetails($query->get());
+        $details = $this->service->buildExport($query->get());
         $json = [];
         foreach ($details as $detail) {
             $json[] = array_values($detail);

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

@@ -77,7 +77,7 @@ class SettlementBillExpressFeeReportController extends Controller
         foreach ($reports as $report) {
             $json[] = [
                 $report['logistic']['name'] ?? '',
-                $report['province'],
+                $report['province']['name'],
                 $report['initial_weight'],
                 $report['initial_amount'],
                 $report['additional_weight'],

+ 0 - 1
app/Http/Controllers/SettlementBillStoreFeeDetailController.php

@@ -61,7 +61,6 @@ class SettlementBillStoreFeeDetailController extends Controller implements Settl
             $query->whereIn('id', explode(',', $request['data']));
         }
         $details = $query->get();
-
         $json = $this->service->buildExport($details);
         $row = ['作业日期', '作业名称', '入库单号', '商品条码', '商品名称', '数量', '单价', '入库费'];
         return Export::make($row, $json, "入库费明细");

+ 0 - 3
app/Http/Controllers/StorageController.php

@@ -153,7 +153,6 @@ sql;
      */
     public function resetCacheShelf()
     {
-        $this->error("缓存架临时关闭,停止使用");
         $this->gate("入库管理-入库-缓存架入库");
         $boxes = request("boxes");
         //清理任务
@@ -184,7 +183,6 @@ sql;
         $result = app("ForeignHaiRoboticsService")->paddingCacheShelf(Station::query()->whereIn("code",$boxes)->get());
         if ($result===null)$this->error("任务下发错误,检查日志");
         if ($result===false)$this->error("已无可用料箱,部分库位填充失败");
-        app("StationService")->locationOccupyMulti($boxes);
         $this->success(["data"=>$data,"boxes"=>$boxes]);
     }
 
@@ -193,7 +191,6 @@ sql;
      */
     public function acquireBox()
     {
-        $this->error("缓存架临时关闭,停止使用");
         $this->gate("入库管理-入库-半箱补货入库");
         $param = request()->only(["track","barCode","lotNum","amount","call"]);
         $track = $param["track"] ?? null;

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

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\Components\ErrorPush;
 use App\Depository;
 use App\Owner;
 use App\Services\common\BatchUpdateService;
@@ -28,6 +29,8 @@ use App\Http\Controllers\api\thirdPart\flux\StoreController as FStoreController;
 
 class StoreController extends Controller
 {
+    use ErrorPush;
+
     public function storage(Request $request)
     {
         if(!Gate::allows('入库管理-入库-查询')){ return redirect(url('/'));  }
@@ -218,12 +221,12 @@ class StoreController extends Controller
         $items = [];
         $toDay = Carbon::now()->toDateTimeString();
         $depositories = [];
-        $traceId = rand(100,999);
+        $traceId = 'W'.rand(0,9).date('ymd').substr($asnno,-4).rand(0,9);
         foreach ($details as $detail) {
             $result = $this->executeSP($detail,$asnno,$depository_code,$db,$quality,$conn,$sql_sp,$traceId);
             if (substr($result, 0, 3) != '000') {
                 oci_close($conn);
-                app('LogService')->log(__METHOD__,"快速入库-FLUX收货失败","ASNNO:".$asnno.";ERROR:".$result);
+                $this->push(__METHOD__."->".__LINE__,"快速入库-FLUX收货失败","ASNNO:".$asnno."Trace:{$traceId}".";ERROR:".$result);
                 return ['success' => false, 'data' => $detail->asnlineno.'收货失败,错误代码:'.$result];
             }
             if (!isset($depositories[$detail->lotatt05]) && $detail->lotatt05){

+ 73 - 0
app/Http/Controllers/TerminalController.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\AsyncResponse;
+use App\Http\Requests\Printer\TerminalRequest;
+use App\Http\Requests\Request;
+use App\Terminal;
+use Illuminate\Support\Facades\Gate;
+
+class TerminalController extends Controller
+{
+    use AsyncResponse;
+
+    // index 页面
+    public function index(TerminalRequest $request)
+    {
+        if (Gate::denies('基础设置-快递打印-终端'))return redirect("/");
+
+        $terminals =  Terminal::query()->orderByDesc('id')->paginate($request['paginate'] ?? 50);
+
+        return view('maintenance.expressPrinting.setting.terminal.index',
+            compact('terminals')
+        );
+    }
+
+    public function storeApi(TerminalRequest  $request): array
+    {
+        if (Gate::denies('基础设置-快递打印-终端-添加'))
+            return ['success' => false, 'message' => '没有对应权限'];
+
+        $terminal = Terminal::query()->create($request->all());
+        return ['success' => true, 'data' => $terminal];
+    }
+
+    public function destroyApi($id): array
+    {
+        if (Gate::denies('基础设置-快递打印-终端-删除'))
+            return ['success' => false, 'message' => '没有对应权限'];
+
+        $terminal = Terminal::query()->find($id);
+        if (!$terminal) return ['success' => false , 'message' => '对应的终端不存在'];
+
+        $terminal->delete();
+        return ['success' => true];
+    }
+
+    public function updateApi(TerminalRequest $request): array
+    {
+        if (Gate::denies('基础设置-快递打印-终端-编辑'))
+            return ['success' => false, 'message' => '没有对应权限'];
+
+        $terminal = Terminal::query()->find($request['id']);
+        if (!$terminal) return ['success' => false, 'message' => '对应的终端不存在'];
+
+        $terminal->update($request->all());
+        return ['success' => true, 'data' => $terminal];
+    }
+
+    public function getTerminalApi($id) :array
+    {
+        $terminal = Terminal::query()->with('printers')->find($id);
+        if (!$terminal)return ['success' => false,'message' => 'was没有记录该ip下的打印机'];
+        return ['success' => true,'data' => $terminal];
+    }
+
+    public function getTerminalByIPApi(Request $request): array
+    {
+        $clientIp = $request->getClientIp();
+        $terminal = Terminal::query()->with('printers')->where('ip')->first();
+        return ['success' => true, 'data' => $terminal];
+    }
+}

+ 62 - 0
app/Http/Controllers/TerminalPrinterController.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Requests\Printer\TerminalPrinterRequest;
+use App\Logistic;
+use App\Terminal;
+use App\TerminalPrinter;
+
+class TerminalPrinterController extends Controller
+{
+
+    public function index(TerminalPrinterRequest $request)
+    {
+//        if (!Gate::allows('基础设置-快递打印-打印机-添加')) return redirect('/');
+
+        $terminalPrinters = TerminalPrinter::query()->with('terminal','logistics')->orderByDesc('terminal_id')->orderByDesc('id')->paginate($request['paginate'] ?? 50);
+        $terminals =  Terminal::query()->get();
+
+        $logistics = Logistic::query()->get();
+
+        return view('maintenance/expressPrinting/setting/printer/index',
+            compact('terminalPrinters','terminals','logistics')
+        );
+    }
+
+    public function storeApi(TerminalPrinterRequest  $request): array
+    {
+//        if (!Gate::allows('基础设置-快递打印-打印机-添加'))
+//            return ['success' => false, 'message' => '没有对应权限'];
+
+        $terminal_printer = TerminalPrinter::query()->create($request->all());
+        $terminal_printer->logistics()->attach($request['logistic_ids']);
+        $terminal_printer->loadMissing('terminal','logistics');
+        return ['success' => true, 'data' => $terminal_printer];
+    }
+
+    public function destroyApi($id): array
+    {
+//        if (!Gate::allows('基础设置-快递打印-打印机-删除'))
+//            return ['success' => false, 'message' => '没有对应权限'];
+
+        $terminal_printer = TerminalPrinter::query()->find($id);
+        if (!$terminal_printer) return ['success' => false , 'message' => '对应的打印机不存在'];
+        $terminal_printer->logistics()->detach();
+        $terminal_printer->delete();
+        return ['success' => true];
+    }
+
+    public function updateApi(TerminalPrinterRequest $request): array
+    {
+//        if (!Gate::allows('基础设置-快递打印-打印机-编辑'))
+//            return ['success' => false, 'message' => '没有对应权限'];
+        $terminal_printer = TerminalPrinter::query()->find($request['id']);
+        if (!$terminal_printer) return ['success' => false, 'message' => '对应的打印机不存在'];
+        $terminal_printer->logistics()->sync($request['logistic_ids']);
+        $terminal_printer->update($request->all());
+        $terminal_printer->load(['terminal','logistics']);
+        return ['success' => true, 'data' => $terminal_printer];
+    }
+
+}

+ 252 - 77
app/Http/Controllers/TestController.php

@@ -3,16 +3,19 @@
 namespace App\Http\Controllers;
 
 use App\Authority;
+use App\Batch;
 use App\Commodity;
 use App\CommodityMaterialBoxModel;
 use App\Components\AsyncResponse;
 use App\Components\ErrorPush;
 use App\ErrorTemp;
 use App\Feature;
+use App\Http\ApiControllers\LoginController;
 use App\Http\Requests\OrderDelivering;
 use App\Jobs\CacheShelfTaskJob;
 use App\Jobs\OrderCreateInstantBill;
 use App\Jobs\OrderCreateWaybill;
+use App\Jobs\SettlementBillReportTask;
 use App\Jobs\StoreCreateInstantBill;
 use App\Jobs\WeightUpdateInstantBill;
 use App\MaterialBox;
@@ -29,9 +32,12 @@ use App\OwnerFeeOperationDetail;
 use App\OwnerFeeStorage;
 use App\OwnerPriceOperation;
 use App\OrderPackageCountingRecord;
+use App\ProcurementCheckSheet;
 use App\RejectedBill;
+use App\Services\BatchService;
 use App\Services\CacheShelfService;
 use App\Services\ForeignHaiRoboticsService;
+use App\Services\OrderPackageReceivedSyncService;
 use App\Services\OrderService;
 use App\Services\OwnerFeeTotalService;
 use App\Services\OwnerLogisticFeeReportService;
@@ -46,9 +52,17 @@ use App\StationTaskMaterialBox;
 use App\Store;
 use App\TaskTransaction;
 use App\Unit;
+use App\User;
+use App\UserDetail;
+use App\UserDutyCheck;
+use App\ValueStore;
 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;
 use Illuminate\Http\Request;
@@ -57,11 +71,18 @@ use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cookie;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Http;
+use Illuminate\Support\Facades\Log;
+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
 {
-    use AsyncResponse,ErrorPush;
+    use AsyncResponse, ErrorPush;
+
     const ASNREFERENCE_2 = 'ASNREFERENCE2';
 
     public function __construct()
@@ -73,99 +94,253 @@ class TestController extends Controller
     {
         return call_user_func([$this, $method], $request);
     }
-    public function test1(){
-        ini_set('max_execution_time',-1);
-        $date = date("Y-m-d H:i:s");
-        ErrorTemp::query()->truncate();
-        OwnerFeeStorage::query()->truncate();
-        OwnerFeeExpress::query()->truncate();
-        OwnerFeeLogistic::query()->truncate();
-        OwnerFeeOperation::query()->truncate();
-        OwnerFeeOperationDetail::query()->truncate();
-        foreach (Order::query()->where("wms_edittime",">=","2021-08-16 00:00:00")
-                     ->where("wms_status","订单完成")
-                     ->where("wms_edittime","<",$date)->get() as $order){
-            $fee = OwnerFeeDetail::query()->where("outer_table_name","orders")->where("outer_id",$order->id)->first();
-            if ($fee){
-                OwnerFeeDetailLogistic::query()->where("owner_fee_detail_id",$fee->id)->delete();
-                $fee->delete();
+    private function valFormat($val):?string
+    {
+        if ($val!==null){
+            $ret = date("Y-m-d H:i:s",strtotime($val))===(string)$val;
+            if ($ret)$val = "to_date('".$val."','yyyy-mm-dd hh24:mi:ss')";
+            else $val = "'".$val."'";
+        }else $val = "null";
+        return $val;
+    }
+    public function test1($task,$amount){
+        DB::connection("oracle")->beginTransaction();
+        try {
+            $columns = '';
+            $values = '';
+            foreach ($task as $key => $val) {
+                if (Str::upper($key) == 'TASKID_SEQUENCE') {
+                    $taskMax = DB::connection("oracle")->selectOne(DB::raw("select MAX(TASKID_SEQUENCE) maxseq from TSK_TASKLISTS where taskid = ?"), [$task->taskid]);
+                    $val = $taskMax->maxseq + 1;
+                }
+                if (Str::upper($key) == 'FMQTY' || Str::upper($key) == 'FMQTY_EACH'
+                    || Str::upper($key) == 'PLANTOQTY' || Str::upper($key) == 'PLANTOQTY_EACH') {
+                    $val -= $amount;
+                    $task->$key = $amount;
+                }
+                $columns .= $key . ",";
+                $values .= $this->valFormat($val) . ",";
             }
-            $a = new Collection([$order]);
-            $this->dispatch(new OrderCreateInstantBill($a));
-        }
-        foreach (Store::query()->where("updated_at",">=","2021-08-16 00:00:00")
-                     ->where("status","已入库")
-                     ->where("updated_at","<",$date)->get() as $store){
-            OwnerFeeDetail::query()->where("outer_table_name","stores")->where("outer_id",$store->id)->delete();
-            $a = new Collection([$store]);
-            $this->dispatch(new StoreCreateInstantBill($a));
+            $columns = mb_substr($columns, 0, -1);
+            $values = mb_substr($values, 0, -1);
+            $sql = <<<sql
+    INSERT INTO TSK_TASKLISTS({$columns}) VALUES({$values})
+sql;
+            dd($sql);
+        }catch (\Exception $e){
+            dd($e);
         }
     }
 
     public function test()
     {
-        ini_set('max_execution_time',-1);
-        $day = (string)\request("day");
-        $d = (int)$day+1;
-        $d = $d<10 ? '0'.(string)$d : (string)$d;
-        foreach (Order::query()->where("wms_edittime",">=","2021-08-{$day} 00:00:00")
-                     ->where("wms_status","订单完成")
-                     ->where("wms_edittime","<","2021-08-{$d} 00:00:00")->get() as $order){
-            $fee = OwnerFeeDetail::query()->where("outer_table_name","orders")->where("outer_id",$order->id)->first();
-            if ($fee){
-                OwnerFeeDetailLogistic::query()->where("owner_fee_detail_id",$fee->id)->delete();
-                $fee->delete();
-            }
-            $a = new Collection([$order]);
-            $this->dispatch(new OrderCreateInstantBill($a));
-        }
-        foreach (Store::query()->where("updated_at",">=","2021-08-{$day} 00:00:00")
-                     ->where("status","已入库")
-                     ->where("updated_at","<","2021-08-{$d} 00:00:00")->get() as $store){
-            OwnerFeeDetail::query()->where("outer_table_name","stores")->where("outer_id",$store->id)->delete();
-            $a = new Collection([$store]);
-            $this->dispatch(new StoreCreateInstantBill($a));
+        TaskTransaction::query()->where("id",">=",280)->delete();
+        /*$a= new StorageService();
+        $a->clearTask(["HAIB1-01-01"]);
+        $task = StationTaskMaterialBox::query()->find(90233);
+        $station = Station::query()->find(11);
+        $foreignHaiRoboticsService = new ForeignHaiRoboticsService();
+        $foreignHaiRoboticsService->putBinToStore_fromCacheShelf($task, $station);
+        dd(1);*/
+        /*$batchService = new BatchService();
+        $batches = Batch::query()->where("id",171829)->get();
+        $batchService->assignTasks($batches);
+        dd();*/
+        /*TaskTransaction::query()->where("id",">=",277)->delete();
+        StationTaskMaterialBox::query()->whereIn("id",[89685,89686,89687])->delete();
+        app("CacheShelfService")->_stationCacheLightOff("HAIB1-01-01");//灭灯
+        app("CacheShelfService")->_stationCacheLightOff("HAIB1-02-01");//灭灯
+        dd(1);*/
+        Station::query()->where("station_type_id",5)->update(["status"=>1]);
+        Cache::forget("CACHE_SHELF_AVAILABLE");
+        $station = ["HAIB1-01-01","HAIB1-02-01"];
+        $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'=>'待处理'
+        ]);
+        $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'=>'待处理'
+        ]);
+        TaskTransaction::query()->insert([[
+            "doc_code" => "test",
+            "bar_code" => "test",
+            "to_station_id" => $stations[0]->id,
+            "material_box_id" => $materials[0]->id,
+            "task_id" => $task1->id,
+            "commodity_id" => 505012,//XUNI03
+            "amount" => 1,
+            "type" => "出库",
+            "status" => 0,
+            "mark" => 2,
+            "bin_number"=>1,
+            "created_at"=>$dateTime,
+            "updated_at"=>$dateTime,
+        ],[
+            "doc_code" => "test",
+            "bar_code" => "test",
+            "to_station_id" => $stations[1]->id,
+            "material_box_id" => $materials[1]->id,
+            "task_id" => $task2->id,
+            "commodity_id" => 505012,//XUNI03
+            "amount" => 1,
+            "type" => "出库",
+            "status" => 0,
+            "mark" => 2,
+            "bin_number"=>1,
+            "created_at"=>$dateTime,
+            "updated_at"=>$dateTime,
+        ],[
+            "doc_code" => "test",
+            "bar_code" => "test",
+            "to_station_id" => 6,
+            "material_box_id" => $materials[2]->id,
+            "task_id" => $task3->id,
+            "commodity_id" => 505012,//XUNI03
+            "amount" => 1,
+            "type" => "出库",
+            "status" => 3,
+            "mark" => 2,
+            "bin_number"=>1,
+            "created_at"=>$dateTime,
+            "updated_at"=>$dateTime,
+        ]]);
+        $foreignHaiRoboticsService = new ForeignHaiRoboticsService();
+        $toLocation = collect($station);
+        $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);
         }
+        app("StationService")->locationOccupyMulti($toLocation->toArray());
     }
 
-    public function test3()
-    {
-        dispatch(new WeightUpdateInstantBill(OrderPackage::query()->find(17000457)));
-        dispatch(new WeightUpdateInstantBill(OrderPackage::query()->find(17000456)));
-    }
-    public function OwnerStoreFeeReportService_recordReport()
+    public function update_order_packages_is_manual_update()
     {
-        /** @var OwnerStoreFeeReportService $service */
-        $service = app('OwnerStoreFeeReportService');
-        $service->recordReport('2021-08-01');
+        $descriptions = Log::query()
+            ->select('description')
+            ->whereBetween('created_at', ['2021-08-31 10:30:00', '2021-08-31 10:35:00'])
+            ->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);
+            OrderPackage::query()
+                ->whereIn('logistic_number', $obj['logistic_numbers'])
+                ->update([
+                    'status' => '无',
+                    'is_manual_update' => false,
+                ]);
+        }
     }
 
-    public function OwnerStoreOutFeeReportService_recordReport()
-    {
-        /** @var OwnerStoreOutFeeReportService $service */
-        $service = app('OwnerStoreOutFeeReportService');
-        $service->recordReport('2021-08-01');
-    }
+    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;
 
-    public function OwnerFeeTotalService_record()
-    {
-        /** @var OwnerFeeTotalService $service */
-        $service = app('OwnerFeeTotalService');
-        $service->record('2021-08-01');
+                $params[] = [
+                    'id' => $item->id,
+                    'order_id' => $item->order->id,
+                    'owner_id' => $owner_id,
+                ];
+                $item->owner_id = $owner_id;
+                $item->save();
+            }
+        });
     }
 
-//快递
-    public function OwnerLogisticFeeReportService_record()
-    {
-        ini_set('max_execution_time',-1);
 
-        /** @var OwnerLogisticFeeReportService $service */
-        $service = app('OwnerLogisticFeeReportService');
-        $service->recordReport('2021-08-01');
-    }
 
-    public function order_packages_sync_routes_flag_init()
+    public function testUpdateInv()
     {
-        OrderPackage::query()->whereNotNull('transfer_status')->update(['sync_routes_flag'=>true]);
+        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());
+            }
+        }
     }
 }

+ 57 - 4
app/Http/Controllers/UserController.php

@@ -8,9 +8,7 @@ use App\Supplier;
 use App\User;
 use App\UserDetail;
 use App\UserWorkgroup;
-use Doctrine\DBAL\Configuration;
 use Exception;
-use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Auth;
@@ -79,7 +77,12 @@ class UserController extends Controller
         $logistics=app('LogisticService')->getSelection(["id","name"],"物流");
         $userWorkgroups=UserWorkgroup::query()->get();
         $suppliers=Supplier::query()->get();
-        return view('maintenance.user.create',['rolesAll'=>$roles,'logistics'=>$logistics,'userWorkgroups'=>$userWorkgroups,'suppliers'=>$suppliers]);
+
+        //工作组 项目组
+        /* @var $user User */
+        $workGroup = app('WarehouseService')->getTreeData();
+        $ownerGroup = app('UserOwnerGroupService')->getSelection();
+        return view('maintenance.user.create',['rolesAll'=>$roles,'logistics'=>$logistics,'userWorkgroups'=>$userWorkgroups,'suppliers'=>$suppliers, 'ownerGroup' => $ownerGroup, 'workGroup'=>$workGroup]);
     }
 
 
@@ -115,7 +118,19 @@ class UserController extends Controller
         $userWorkgroup=$user->userWorkgroups()->first();
         $supplierUser=$user->suppliers()->get();
         $suppliers=Supplier::query()->get();
-        return view('maintenance.user.edit',compact('user','rolesAll','roles','logistics','logisticUser','userWorkgroups','userWorkgroup','suppliers','supplierUser'));
+        //工作组 项目组
+        /* @var $user User */
+        $workGroup = app('WarehouseService')->getTreeData();
+        $group = $user->workGroups()->get();
+        $groups = [];
+        foreach ($group as $v){
+           array_push($groups,'g'.$v->id);
+           array_push($groups,'w'.$v->warehouse_id);
+        }
+        $workGroups = $groups;
+        $ownerGroup = app('UserOwnerGroupService')->getSelection();
+        $ownerGroups =  $user->ownerGroups->pluck('id');
+        return view('maintenance.user.edit',compact('user','rolesAll','roles','logistics','logisticUser','userWorkgroups','userWorkgroup','suppliers','supplierUser','workGroup','workGroups','ownerGroup','ownerGroups'));
     }
 
     /**
@@ -165,6 +180,18 @@ class UserController extends Controller
             if (!$user->userDetail) UserDetail::query()->create(['user_id'=>$user->id,'mobile_phone'=>$phone]);
             UserDetail::query()->where('user_id',$user->id) ->update(['mobile_phone'=>$phone]);
         }
+
+        //工作组
+        $work_id = [];
+        $treeData = $request->input('treeData')??[];
+        foreach ($treeData as $v){
+            if (strrpos($v,'g') === 0) array_push($work_id, mb_substr($v,1));
+        }
+        if ($work_id)$user->workGroups()->sync($work_id);
+        //项目组
+        $owners = $request->input('ownerGroup')??'';
+        if ($owners)$user->ownerGroups()->sync($owners);
+
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
         app("UserService")->clearUserCache($user);
         return redirect('maintenance/user/')->with('successTip',"成功修改用户“{$user['name']}”!");
@@ -198,4 +225,30 @@ class UserController extends Controller
         $user->update(["password" => Hash::make(request("pwd"))]);
         $this->success();
     }
+
+    //工作组
+    public function saveWorkGroups(Request $request)
+    {
+        if(!Gate::allows('用户-编辑')){ return redirect(url('/'));  }
+        $params = $request->all();
+        $work_id = [];
+        foreach ($params['workGroups'] as $v){
+            if (strrpos($v,'g') === 0 ) array_push($work_id, mb_substr($v,1));
+        }
+        /* @var $user User */
+        $user = User::query()->find($params['id']);
+        $user->workGroups()->sync($work_id);
+        return ['success'=>true];
+    }
+
+    //工作组
+    public function saveOwnerGroups(Request $request)
+    {
+        if(!Gate::allows('用户-编辑')){ return redirect(url('/'));  }
+        $params = $request->all();
+        /* @var $user User */
+        $user = User::query()->find($params['id']);
+        $user->ownerGroups()->sync($params['ownerGroups']);
+        return ['success'=>true];
+    }
 }

+ 244 - 42
app/Http/Controllers/WaybillController.php

@@ -5,16 +5,18 @@ namespace App\Http\Controllers;
 
 use App\CarType;
 use App\Components\AsyncResponse;
-use App\Logistic;
 use App\Owner;
 use App\Region;
 use App\Services\CarTypeService;
 use App\Services\LogisticService;
+use App\Services\LogService;
 use App\Services\OwnerService;
 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;
 use App\WaybillOnTop;
@@ -55,16 +57,21 @@ class WaybillController extends Controller
      */
     public function index(Request $request,OwnerService $ownerService,LogisticService $logisticService)
     {
-        if(!Gate::allows('运输管理-运单-查询')){ return view("exception.authority");  }
         $paginateParams = $request->input();
         $waybills=app('waybillService')->paginate($request->input());
+        $mac_addr = getMacAddr();
+        $print = TerminalPrinter::with(['terminal','logistics'])
+            ->whereHas('terminal',function ($query)use($mac_addr){$query->where('ip',$mac_addr);})
+            ->whereHas('logistics',function ($query){$query->where('logistic_id',15);})
+            ->first();
+        $print = $print->printer_name??'EK100B';
         return view('transport.waybill.index', [
             'waybills' => $waybills,
             'logistics' => $logisticService->getSelection(["id","name"],"物流"),
             'owners' => $ownerService->getIntersectPermitting(),
             "carTypes" => CarType::query()->get(),
             'paginateParams'=>$paginateParams,
-            'uriType'=>$request->uriType??'']);
+            'uriType'=>$request->uriType??'','print_name'=> $print]);
     }
 
 
@@ -118,12 +125,14 @@ class WaybillController extends Controller
     public function update(Request $request, $id,WaybillPriceModelService $waybillPriceModelService,
                            LogisticService $logisticService,WaybillPayoffService $waybillPayoffService)
     {
-        if(!Gate::allows('运输管理-运单-调度')){ return view("exception.authority");  }
+        if(!Gate::allows('运输管理-运单-调度') && $request->type != '德邦物流'){ return view("exception.authority");  }
         if (!$request->warehouse_weight && $request->warehouse_weight_unit_id)$request->offsetUnset('warehouse_weight_unit_id');
         if (!$request->warehouse_weight_other && $request->warehouse_weight_unit_id_other)$request->offsetUnset('warehouse_weight_unit_id_other');
         if (!$request->carrier_weight && $request->carrier_weight_unit_id)$request->offsetUnset('carrier_weight_unit_id');
         if (!$request->carrier_weight_other && $request->carrier_weight_unit_id_other)$request->offsetUnset('carrier_weight_unit_id_other');
+        if ($request->type == '德邦物流' && empty($request->carrier_bill)) $request->offsetSet('carrier_bill', 'dbwl');
         $this->validatorWaybillDispatch($request,$id)->validate();
+        if ($request->carrier_bill == 'dbwl')$request->offsetSet('carrier_bill', '');
         $waybillPayoffParam = [];
         $waybillPayoffParam['total_receivable']=0;
         /** @var WaybillService */
@@ -185,7 +194,7 @@ class WaybillController extends Controller
             DB::rollBack();
             return "调度失败".$e->getMessage();
         }
-        return redirect('transport/waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”调度成功 '. ($msg??''));
+        return redirect('transport/waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”创建成功 '. ($msg??''));
     }
 
     public function checkWaybillPriceModel($logistic_id,$destination_city_id,$carrier_weight,$carrier_weight_unit_id){
@@ -767,19 +776,46 @@ SQL;
         ])->direct();
     }
 
-    //发运
-    public function delivering(Request $request){
-        if (!Auth::user())return view('exception.login');
-        $waybills= app('waybillService')->paginate($request->input());
+    private function deliveringQuery(Request $request): Builder
+    {
+        $waybills= Waybill::query()->where("type","专线")->with(["order","logistic"])
+        ->whereNotNull("logistic_id")->whereNotNull("deliver_at")->whereIn("status",["已审核","待终审"]);
         if (!Auth::user()->isSuperAdmin()){
-            $carriersUsers=DB::table('carrier_user')->where('user_id',Auth::id())->get();
+            $carriersUsers=DB::table('logistic_user')->where('user_id',Auth::id())->get();
             $carrierIds=array_column($carriersUsers->toArray(),'logistic_id');
-            $waybills=$waybills->whereIn("logistic_id",$carrierIds);
+            if ($carrierIds)$waybills->whereIn("logistic_id",$carrierIds);
         }
-        return view('transport.waybill.delivering',compact('waybills'));
+        $searchText = $request->get("searchText","");
+        if ($searchText)$waybills->where(function ($query)use($searchText){
+            $query->where("waybill_number",'like','%'.$searchText.'%')->orWhere("carrier_bill",'like','%'.$searchText.'%');
+        });
+        $lastId = $request->get("lastId","");
+        if ($lastId)$waybills->where("id","<",$lastId);
+        $deliverAt = $request->get("deliverAt");
+        if ($deliverAt)$waybills->where("deliver_at",$deliverAt);
+        $date = $request->get("date");
+        if ($date)$waybills->where("deliver_at",'like',$date."%");
+        return $waybills;
+    }
+    //发运
+    public function delivering(Request $request){
+        $groups = $this->deliveringQuery($request)->selectRaw("date_format(deliver_at, '%Y-%m-%d') date,sum(pick_up_fee) pick_up_fee_total")
+            ->orderByDesc(DB::raw("date"))->groupByRaw("date")->get();
+        $searchText = $request->get("searchText","");
+        return view('transport.waybill.delivering',compact('groups',"searchText"));
+    }
+
+    /**
+     * 懒加载发运数据
+     */
+    public function loadData(Request $request)
+    {
+        if (!Auth::user())$this->error("登录信息失效");
+        $this->success($this->deliveringQuery($request)->orderByDesc("id")->get());
     }
     //承运商提交
     public function storeCarrierBill(Request $request){
+        if(!Gate::allows("运输管理-承运商调度"))return ["error"=>"无权操作!"];
         $errors=Validator::make($request->input(),[
             'id'=>'required|integer',
             'carrier_bill'=>'required',
@@ -793,16 +829,28 @@ SQL;
             'numeric'=>':attribute 应为数字',
             'required_with'=>':attribute 重量与体积至少存在一项',
         ],[
-            'carrier_bill'=>'专线运单号',
+            'carrier_bill'=>'运单号',
             'inquire_tel'=>'查件电话',
             'amount'=>'件数',
             'carrier_weight'=>'体积',
             'carrier_weight_other'=>'重量',
         ])->errors();
+        $unit = app("UnitService")->getUnit("kg");
+        $unit1 = app("UnitService")->getUnit("件");
+        $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);
+        $request->offsetSet("carrier_weight_unit_id_other",$unit->id);
+        $request->offsetSet("amount_unit_id",$unit1->id);
+        $request->offsetSet("status","待终审");
         $waybill->fill($request->input());
+        WaybillAuditLog::query()->create([
+            'waybill_id'=>$waybill->id,
+            'audit_stage'=>'调度阶段',
+            'user_id'=>Auth::id(),
+        ]);
         $waybill->update();
         return $waybill;
     }
@@ -844,6 +892,7 @@ SQL;
             'logistic_id'=>'required_without:order_id|integer',
             'carrier_bill'=>"sometimes|required|max:50|unique:waybills,carrier_bill,$id",
             'fee'=>'sometimes|nullable|min:0|numeric|max:999999',
+            'inquire_tel'=>'required',
             'carType_id'=>'sometimes|required|integer',
             'other_fee'=>'sometimes|nullable|min:0|numeric|max:999999',
             'charge'=>'sometimes|nullable|min:0|numeric|max:999999',
@@ -879,6 +928,7 @@ SQL;
             'integer'=>':attribute 必须为数字',
         ],[
             'logistic_id'=>'承运商',
+            'inquire_tel'=>'查件电话',
             'carrier_bill'=>'承运商单号',
             'fee'=>'运费',
             'other_fee'=>'其他费用',
@@ -1042,7 +1092,8 @@ SQL;
     //按日输入专线费
     public function dailyBilling(Request $request): array
     {
-        if(!Gate::allows('运输管理-运单-按日计算专线费')){return ['success'=>false,'message'=>'没有权限'];}
+        if(!Gate::allows('运输管理-运单-按日计算专线费')
+        && !Gate::allows('运输管理-承运商调度')){return ['success'=>false,'message'=>'没有权限'];}
         $dailyBilling=$request->input('param');
         $waybills=app('waybillService')->dailyBilling($dailyBilling);
         if ($waybills=='无数据')return ['success'=>false,'message'=>'当前选定发货日期没有任何记录'];
@@ -1122,34 +1173,7 @@ SQL;
                 $query->where("audit_stage","合并运单");
             })->whereIn("id",$ids)->get();
             if ($waybills->count()==0)$this->error("运单不存在或非合并运单");
-            foreach ($waybills as $waybill){
-                $codes = explode(",",$waybill->wms_bill_number);
-                $bills = explode(",",$waybill->source_bill);
-                $remark = explode(",",$waybill->ordering_remark);
-                if (!$codes)continue;
-                /** @var Collection $destroys */
-                foreach (Waybill::onlyTrashed()->whereIn("wms_bill_number",$codes)->get() as $obj){
-                    unset($codes[array_search($obj->wms_bill_number,$codes)]);
-                    unset($bills[array_search($obj->source_bill,$bills)]);
-                    if (array_search($obj->ordering_remark,$remark)===false)unset($bills[array_search($obj->ordering_remark,$remark)]);
-                    $waybill->charge -= (double)$obj->charge;
-                    $waybill->collect_fee -= (double)$obj->collect_fee;
-                    $waybill->other_fee -= (double)$obj->other_fee;
-                    $waybill->warehouse_weight_other -= (double)$obj->warehouse_weight_other;
-                    $waybill->warehouse_weight -= (double)$obj->warehouse_weight;
-                }
-                Waybill::onlyTrashed()->whereIn("wms_bill_number",explode(",",$waybill->wms_bill_number))->restore();
-                $waybill->merge_owner = null;
-                $waybill->source_bill = implode(",",$bills);
-                $waybill->wms_bill_number = implode(",",$codes);
-                $waybill->ordering_remark = implode(",",$remark);
-                $waybill->update();
-                WaybillAuditLog::query()->create([
-                    'waybill_id'=>$waybill->id,
-                    'audit_stage'=>'拆单返回',
-                    'user_id'=>Auth::id(),
-                ]);
-            }
+            foreach ($waybills as $waybill)$this->split($waybill);
             DB::commit();
         }catch (\Exception $e){
             DB::rollBack();
@@ -1158,6 +1182,38 @@ SQL;
         $this->success(count($ids)==$waybills->count() ? '运单拆单完毕' : '部分运单不符合拆单条件');
     }
 
+    private function split($waybill)
+    {
+        $codes = explode(",",$waybill->wms_bill_number);
+        if (!$codes || count($codes)<2)return;
+        $bills = explode(",",$waybill->source_bill);
+        $remark = explode(",",$waybill->ordering_remark);
+        /** @var Collection $waybills */
+        $waybills = Waybill::onlyTrashed()->whereIn("wms_bill_number",$codes)->get();
+        if (!$waybills->count())return;
+        foreach ($waybills as $obj){
+            unset($codes[array_search($obj->wms_bill_number,$codes)]);
+            unset($bills[array_search($obj->source_bill,$bills)]);
+            if (array_search($obj->ordering_remark,$remark)===false)unset($bills[array_search($obj->ordering_remark,$remark)]);
+            $waybill->charge -= (double)$obj->charge;
+            $waybill->collect_fee -= (double)$obj->collect_fee;
+            $waybill->other_fee -= (double)$obj->other_fee;
+            $waybill->warehouse_weight_other -= (double)$obj->warehouse_weight_other;
+            $waybill->warehouse_weight -= (double)$obj->warehouse_weight;
+        }
+        Waybill::onlyTrashed()->whereIn("wms_bill_number",explode(",",$waybill->wms_bill_number))->restore();
+        $waybill->merge_owner = null;
+        $waybill->source_bill = implode(",",$bills);
+        $waybill->wms_bill_number = implode(",",$codes);
+        $waybill->ordering_remark = implode(",",$remark);
+        $waybill->update();
+        WaybillAuditLog::query()->create([
+            'waybill_id'=>$waybill->id,
+            'audit_stage'=>'拆单返回',
+            'user_id'=>Auth::id(),
+        ]);
+    }
+
     /**
      * 快递面单打印 :暂时支持 德邦
      */
@@ -1198,4 +1254,150 @@ SQL;
         }
         $this->error('打印失败');
     }
+
+    /**
+     * 运输发货在PC-APP上临时入口
+     */
+    public function shipment()
+    {
+        $logistics = app("LogisticService")->getSelection(['id','name','tag'],"物流");
+        return view("transport.waybill.android.shipment",compact("logistics"));
+    }
+    /**
+     * 发货与合并
+     */
+    public function shipmentAndMerge()
+    {
+        $this->gate("运输管理-编辑");
+        if (!\request("logistic"))$this->error("未选择承运商");
+        $waybill = Waybill::query()->with("waybillAuditLogs:waybill_id,audit_stage")->where("waybill_number",\request("waybill"))
+            ->whereNotIn("status",["已完结","无模型"])->first();
+        if (!$waybill)$this->error("运单禁止操作");
+        if ($waybill->deliver_at){
+            if ($waybill->waybillAuditLogs->where("audit_stage","单独发货")->count())$this->split($waybill);
+            else if(!$waybill->waybillAuditLogs->where("audit_stage","合单发货")->count())
+                $this->error("运单已发货,请勿重复调配");
+        }
+
+        $codes = explode("\n",\request("order"));
+        $waybills = Waybill::query()->whereIn("wms_bill_number",$codes)
+            ->where("id","!=",$waybill->id)
+            ->whereNull("deliver_at")
+            ->whereNotIn("status",["已完结","无模型"])->get();
+        if ($waybills->count()){
+            if ($waybills->count()<count($codes)-1)$this->error("存在非法订单");
+            $destroys = [];
+            $owner = [$waybill->owner_id];
+            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)) ||
+                    (!$waybill->order && ($item->recipient!=$waybill->recipient
+                            || $item->recipient_mobile!=$waybill->recipient_mobile));
+                if ($identical)$this->error("订单信息不一致,无法统一发货");
+                $destroys[] = $item->id;
+                $waybill->source_bill .= $item->source_bill ? ",".$item->source_bill : '';
+                $waybill->wms_bill_number .= $item->wms_bill_number ? ",".$item->wms_bill_number : '';
+                $waybill->charge += (double)$item->charge;
+                $waybill->collect_fee += (double)$item->collect_fee;
+                $waybill->other_fee += (double)$item->other_fee;
+                $waybill->warehouse_weight_other += (double)$item->warehouse_weight_other;
+                $waybill->warehouse_weight += (double)$item->warehouse_weight;
+                $waybill->ordering_remark = $waybill->ordering_remark ? $waybill->ordering_remark.",".$item->ordering_remark : $item->ordering_remark;
+                $owner[] = $item->owner_id;
+            }
+            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);
+            $waybill->deliver_at = date("Y-m-d H:i:s");
+            $waybill->logistic_id = \request("logistic");
+            if ($waybill->status=='未审核')$waybill->status = '已审核';
+            $waybill->update();
+            Waybill::destroy($destroys);
+            WaybillAuditLog::query()->create([
+                'waybill_id'=>$waybill->id,
+                'audit_stage'=>'合单发货',
+                'user_id'=>Auth::id(),
+            ]);
+        }else{
+            WaybillAuditLog::query()->create([
+                'waybill_id'=>$waybill->id,
+                'audit_stage'=>'单独发货',
+                'user_id'=>Auth::id(),
+            ]);
+            $update = ["deliver_at"=>date("Y-m-d H:i:s"),"logistic_id"=>\request("logistic")];
+            if ($waybill->status=='未审核')$update["status"] = '已审核';
+            $waybill->update($update);
+        }
+        $this->success();
+    }
+
+    /**
+     * 运输发货在PC-APP上临时入口
+     */
+    public function waybillDispatch()
+    {
+        return view("transport.waybill.android.dispatch");
+    }
+
+    /**
+     * 搜索运单获取信息
+     */
+    public function searchWaybill()
+    {
+        $this->success($this->dispatchCheck(\request("bill")));
+    }
+
+    private function dispatchCheck($bill)
+    {
+        if (!$bill)$this->error("参数异常");
+        $waybill = Waybill::query()->select(["id","carrier_bill","inquire_tel","carrier_weight_other","carrier_weight","amount","deliver_at"])
+            ->where("waybill_number",$bill)->whereNotIn("status",["已完结","无模型"])->first();
+        if(!$waybill)$this->error("非法运单号");
+        if ($waybill->carrier_bill)$this->error("运单已发货,请勿重复调配");
+        if (!$waybill->deliver_at)$this->error("运单未发货,无法调配");
+        return $waybill;
+    }
+
+    /**
+     * 调配
+     *
+     */
+    public function dispatchSubmit()
+    {
+        $this->gate("运输管理-编辑");
+        if (!\request("waybill") || !\request("phone")
+            || !\request("volume") || !\request("weight") || !\request("amount"))$this->error("非法参数");
+        $waybill = $this->dispatchCheck(\request("waybill"));
+        $unit = app("UnitService")->getUnit("kg");
+        $unit1 = app("UnitService")->getUnit("件");
+        $waybill->update([
+            "carrier_bill"  => \request("waybill"),
+            "inquire_tel"   => \request("phone"),
+            "carrier_weight_other" => \request("volume"),
+            "carrier_weight" => \request("weight"),
+            "amount" => \request("amount"),
+            "amount_unit_id" => $unit->id,
+            "carrier_weight_unit_id" => $unit->id,
+            "carrier_weight_unit_id_other" => $unit1->id,
+        ]);
+        WaybillAuditLog::query()->create([
+            'waybill_id'=>$waybill->id,
+            'audit_stage'=>'调度阶段',
+            'user_id'=>Auth::id(),
+        ]);
+        $this->success();
+    }
+
+    public function appendSubjoinFee()
+    {
+        $this->gate("运输管理-承运商调度");
+        $id = \request("id");
+        $subjoinFee = \request("subjoinFee");
+        if (!$id || !$subjoinFee)$this->error("非法参数");
+        if (Waybill::query()->where("id",$id)->update(["subjoin_fee"=>$subjoinFee]) == 0)$this->error("修改失败,运单信息发送变更");
+        LogService::log("运输附加费","调度商添加","录入人:".Auth::id()." | 修改{$id}费用为:".$subjoinFee);
+        $this->success();
+    }
 }

+ 63 - 118
app/Http/Controllers/WorkOrderController.php

@@ -4,155 +4,100 @@ namespace App\Http\Controllers;
 
 use App\Filters\WorkOrderFilters;
 use App\Logistic;
+use App\OrderIssue;
+use App\OrderIssueType;
+use App\Services\OwnerService;
 use App\Services\WorkOrderService;
-use App\Services\WorkOrderTypeService;
 use App\WorkOrder;
-use App\WorkOrderType;
-use Illuminate\Contracts\Foundation\Application;
-use Illuminate\Contracts\View\Factory;
 use Illuminate\Database\Eloquent\Builder;
-use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
-use Illuminate\Routing\Redirector;
 use Illuminate\Support\Facades\Gate;
-use Illuminate\View\View;
 
 class WorkOrderController extends Controller
 {
-    /**
-     * 工单主页
-     *
-     * @param Request $request
-     * @param WorkOrderFilters $filters
-     * @return Application|Factory|RedirectResponse|Redirector|View
-     */
-    public function index(Request $request, WorkOrderFilters $filters)
-    {
-        if (!Gate::allows('订单管理-工单处理-查询')) return redirect('/');
-
-        $workOrders = WorkOrder::query()->filter($filters)->with(['type', 'creator', 'order' => function ($query) {
-            /** @var $query Builder */
-            $query->with('packages', 'issue', 'logistic');
-        }, 'reviewer'])->orderByDesc('created_at', 'grad', 'status')->paginate($request['paginate'] ?? 50);
-        $logistics = Logistic::all();
-        return view('order.workOrder.index', compact('workOrders', 'logistics'));
-    }
-
-    public function create()
-    {
-        if (!Gate::allows('订单管理-工单处理-创建')) return redirect('/');
-        $workOrderTypes = WorkOrderType::query()->with('childTypes')->get();
-        $grads = WorkOrder::$enums['grad'];
-        array_shift($grads);
-        return view('order.workOrder.create', compact('workOrderTypes', 'grads'));
-    }
-
-
-    public function store(Request $request, WorkOrderService $service)
-    {
-        if (!Gate::allows('订单管理-工单处理-创建')) return redirect('/');
-        $result = $service->create($request->all());
-        $workOrderTypes = WorkOrderType::query()->with('childTypes')->get();
-        $grads = WorkOrder::$enums['grad'];
-        array_shift($grads);
-        return view('order.workOrder.create', compact('workOrderTypes', 'result', 'grads'));
-    }
-
-    /**
-     * 生成订单拦截工单
-     * @param Request $request
-     * @param WorkOrderService $service
-     * @return array
-     */
-    public function interceptOrderApi(Request $request, WorkOrderService $service): array
-    {
-        if (!Gate::allows('订单管理-订单-生成工单')) return ['success' => false, 'message' => '没有对应的创建权限'];
-
-        $uniquely_tags = $request['order_nos'];
-
-        $work_order_type = app(WorkOrderTypeService::class)->findOrCreate('订单拦截', 'orders', '订单', '订单拦截');
-
-        $result = $service->exists($work_order_type['id'], $uniquely_tags);     // 检查订单号和工单类型是否有对应的工单
-
-        if ($result['success'])
-            return ['success' => false, 'message' => join(",", array($result['data'])) . "已有对应的订单拦截工单"];
-
-        return $service->interceptOrder($work_order_type, $uniquely_tags, $request['grad']);
-    }
 
-    /**
-     * 生成订单修改工单
-     * @param Request $request
-     * @param WorkOrderService $service
-     * @return array
-     */
-    public function editOrderReceiveInfoApi(Request $request,WorkOrderService $service): array
+    public function index(Request $request, WorkOrderFilters $filters, WorkOrderService $service)
     {
-        if (!Gate::allows('订单管理-订单-生成工单')) return ['success' => false, 'message' => '没有对应的创建权限'];
-
-        if (is_array($request['order_nos'])) return ['success' => false,'message' => '参数错误'];
-
-        $uniquely_tag = $request['order_nos'];
-
-        $work_order_type = app(WorkOrderTypeService::class)->findOrCreate('订单收件信息修改', 'orders', '订单', '订单收件信息修改');
-
-        $result = $service->exists($work_order_type['id'], $uniquely_tag);     // 检查订单号和工单类型是否有对应的工单
-
-        if($result['success'])
-            return ['success' => false,'message' => join(",", array($result['data'])) . "已有对应的订单信息修改工单"];
-
-        return $service->editOrder($work_order_type,$uniquely_tag,$request['remake']);
+        if (Gate::denies('订单管理-工单处理-查询')) return redirect('/');
+        $workOrders = WorkOrder::query()->filter($filters)->defaultWith()->orderBy('created_at')->orderByDesc('status')->paginate($request['paginate'] ?? 50);
+        $logistics = Logistic::all();
+        $orderIssueTypes = $service->getIssueType();
+        $owners = app('OwnerService')->getAuthorizedOwners();
+        $service->tags($workOrders);
+        return view('order.workOrder.index', compact('workOrders', 'logistics', 'orderIssueTypes','owners'));
     }
 
-    /**
-     * 工单审核
-     * @param Request $request
-     * @param WorkOrderService $service
-     * @return array
-     */
+    // 审核 api
     public function reviewApi(Request $request, WorkOrderService $service): array
     {
-        if (!Gate::allows('订单管理-工单处理-审核')) return ['success' => false, 'message' => '没有对应的编辑权限'];
+        if (Gate::denies('订单管理-工单处理-审核')) return ['success' => false, 'message' => '没有对应的编辑权限'];
         $workOrder = WorkOrder::query()->find($request['id']);
         return $service->review($workOrder);
     }
 
-    /**
-     * 生成问题件
-     * @param Request $request
-     * @param WorkOrderService $service
-     * @return array
-     */
-    public function createOrderIssueApi(Request $request, WorkOrderService $service): array
+    // 批量审核 api
+    public function batchReviewApi(Request $request,WorkOrderService  $service): array
+    {
+        if(Gate::denies('订单管理-工单处理-审核'))return ['success' => false, 'message' => '没有对应的编辑权限'];
+        if (WorkOrder::query()->whereIn('id',$request['ids'])->whereNotNull('review_at')->exists())
+            return ['success' => false, 'message' => '选中的工单已有审核完成,刷新页面重试'];
+        $work_orders = WorkOrder::query()->whereIn('id',$request['ids'])->get();
+        $service->tags($work_orders);
+        return $service->batchReview($work_orders);
+    }
+
+    // 生成问题件 api
+    public function buildOrderIssueApi(Request $request, WorkOrderService $service): array
     {
-        if (!Gate::allows('订单管理-订单问题件生成'))
+        if (Gate::denies('订单管理-订单问题件生成'))
             return ['success' => false, 'message' => '没有对应权限'];
         $work_orders = WorkOrder::query()->whereIn('id', $request['ids'])->get();
         if (count($work_orders) == 0) return ['success' => false, 'message' => '刷新当前页面重试'];
-        return $service->createOrderIssue($work_orders);
+        if (OrderIssue::query()->whereIn('order_id',$work_orders->map(function($item){return $item['order_id'];}))->exists()){
+            return ['success' => false, 'message' => '已有对应的问题件'];
+        }
+        $result = $service->buildOrderIssue($work_orders);
+        if (!$result['success']) return $result;
+        $workOrders = WorkOrder::query()->with(['type', 'creator', 'order' => function ($query) {
+            /** @var $query Builder */
+            $query->with('packages', 'issue', 'logistic');
+        }, 'reviewer','issueType'])->whereIn(  'id',$request['ids'])->get();
+        $service->tags($workOrders);
+        return ['success' => true ,'data' => $workOrders];
     }
 
-
-    public function show(WorkOrder $workOrder)
+    // 创建工单 api
+    public function storeApi(Request $request, WorkOrderService $service):array
     {
-        //
+        if (Gate::denies('订单管理-订单-生成工单'))
+            return ['success' => false, 'message' => '没有对应权限'];
+        $params = $request['params'];
+        if (count($params) == 0) return ['success' => false,'message' => '参数异常'];
+        app('OrderService')->syncOrderByCodes(array_map(function($param){
+            return $param['order_no'];
+        },$params));
+        return  $service->build($request['params']);
     }
 
-
-    public function edit(WorkOrder $workOrder)
+    // 修改问题类型
+    public function updateIssueTypeApi(Request $request): array
     {
-        //
-    }
-
+        if (Gate::denies('订单管理-工单处理-审核'))
+            return ['success' => false,'message' => '没有对应权限'];
 
-    public function update(Request $request, WorkOrder $workOrder)
-    {
-        //
+        WorkOrder::query()->where('id',$request['id'])->update(['order_issue_type_id' => $request['type_id']]);
+        return ['success' => true];
     }
 
-
-    public function destroy(WorkOrder $workOrder)
+    // 批量修改问题件类型
+    public function batchUpdateIssueTypeApi(Request $request,WorkOrderService $service): array
     {
-        //
+        if (Gate::denies('订单管理-工单处理-审核'))
+            return ['success' => false,'message' => '没有对应权限'];
+        WorkOrder::query()->whereIn('id',$request['ids'])->update(['order_issue_type_id' => $request['type']]);
+        $items = WorkOrder::query()->defaultWith()->whereIn('id',$request['ids'])->get();
+        $service->tags($items);
+        return ['success' => true,'data' => $items];
     }
+
 }

+ 1 - 6
app/Http/Controllers/api/thirdPart/flux/SortingController.php

@@ -4,15 +4,11 @@ namespace App\Http\Controllers\api\thirdPart\flux;
 
 use App\Batch;
 use App\Http\Controllers\Controller;
-use App\OracleActAllocationDetails;
 use App\Order;
-use App\OrderBin;
 use App\OrderCommodity;
-use App\Owner;
-use App\Services\CommodityService;
-use Carbon\Carbon;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
+use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Validator;
 use Zttp\Zttp;
 
@@ -179,7 +175,6 @@ class SortingController extends Controller
                 'bin'=>$order->bin()->first()['number']
             ];
         });
-        $response=null;
         try {
             $response=Zttp::post($apiUrl,$sendingData);
         }catch (\Exception $e){

+ 3 - 1
app/Http/Controllers/api/thirdPart/goodscan/PackageController.php

@@ -5,14 +5,16 @@ namespace App\Http\Controllers\api\thirdPart\goodscan;
 
 use App\Services\LogService;
 use App\Services\weight\GoodScanWeightService;
+use App\WeightLog;
 use Illuminate\Http\Request;
-use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Validator;
 
 class PackageController
 {
     public function new_(Request $request)
     {
+        WeightLog::query()->create(['content' => json_encode($request->all()),'interface' => 'GoodScan']);
+
         app('LogService')->log(__METHOD__, 'GoodScan weightApi add' . __FUNCTION__, json_encode($request->getContent()));
         $requestInput = [];
         foreach ($request->input() as $key => $item) {

+ 2 - 0
app/Http/Controllers/api/thirdPart/hengli/PackageController.php

@@ -6,12 +6,14 @@ namespace App\Http\Controllers\api\thirdPart\hengli;
 use App\Http\Controllers\api\thirdPart\weight\WeightBaseController;
 use App\Services\LogService;
 use App\Services\weight\HengLiWeightService;
+use App\WeightLog;
 use Illuminate\Http\Request;
 
 class PackageController extends WeightBaseController
 {
     public function new_(Request $request)
     {
+        WeightLog::query()->create(['content' => json_encode($request->all()),'interface' => 'HengLi']);
         $errors = $this->validator($request);
         if(count($errors)>0){
             return json_encode(['success' => false,'message' => $errors],JSON_UNESCAPED_UNICODE);

+ 2 - 0
app/Http/Controllers/api/thirdPart/weight/PackageController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers\api\thirdPart\weight;
 use App\Http\Controllers\Controller;
 use App\Services\LogService;
 use App\Services\weight\HaoChuangWeightService;
+use App\WeightLog;
 use Illuminate\Http\Request;
 use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Validator;
@@ -13,6 +14,7 @@ class PackageController extends Controller
 {
     public function new_(Request $requestInitial)
     {
+        WeightLog::query()->create(['content' => json_encode($requestInitial->all()),'interface' => 'HaoChuang']);
         $request = [];
         foreach ($requestInitial->all() as $k => $v) {
             $request[strtolower($k)] = $v;

+ 4 - 0
app/Http/Controllers/api/thirdPart/weight/WeightBaseController.php

@@ -406,6 +406,10 @@ class WeightBaseController
             if(strlen($a) == strlen($b))return 0;
             return strlen($a) < strlen($b) ? 1 : -1;
         });
+        if (count($codes) > 1){
+            $item = OrderPackage::query()->whereIn('logistic_number',$codes)->first();
+            if ($item)return $item->logistic_number;
+        }
         return $codes[0] ?? null;
     }
 

+ 3 - 3
app/Http/Kernel.php

@@ -2,6 +2,7 @@
 
 namespace App\Http;
 
+use App\Http\Middleware\AuthorizingApi;
 use App\Http\Middleware\CheckCsrfToken;
 use App\Http\Middleware\LogPostRequest;
 use Illuminate\Foundation\Http\Kernel as HttpKernel;
@@ -43,9 +44,7 @@ class Kernel extends HttpKernel
         ],
 
         'api' => [
-            LogPostRequest::class,
-//            'throttle:60,1',
-            'bindings',
+            //'bindings', //隐性转换参数为数据库模型 先在API中去除此中间件
         ],
         'apiLocal' => [
             LogPostRequest::class,
@@ -77,6 +76,7 @@ class Kernel extends HttpKernel
         'auth.api' => \App\Http\Middleware\ApiAuth::class,
         'procurement.auth.api' => \App\Http\Middleware\ProcurementApiAuth::class,
         'check.token' => CheckCsrfToken::class,
+        'authorizing' => AuthorizingApi::class,
     ];
 
     /**

+ 53 - 0
app/Http/Middleware/AuthorizingApi.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Firebase\JWT\ExpiredException;
+use Firebase\JWT\JWT;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Cache;
+
+class AuthorizingApi
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  Request  $request
+     * @param  Closure  $next
+     * @return mixed
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        $token = $request->header("token");
+        if (!$token) return response()->json([
+                        'message' => '没有认证,请前去认证',
+                        'status_code' => 401,
+                    ]);
+        try {
+            $publicKey = Cache::remember("TOKEN_PUBLIC_KEY",7200,function (){
+                return file_get_contents(base_path().'/public.pem');
+            });
+        }catch (\Exception $e){
+            $response["status_code"] = 410;
+            if (strpos($e->getMessage(),"No such file or directory")!==false)$response["message"] = "服务器异常,资源丢失";
+            else $response["message"] = "访问某些资源失败";
+            return response()->json($response);
+        }
+        try {
+            $payload = JWT::decode($token, $publicKey, ['RS256']);
+            $user = app("UserService")->getOrRefreshCache($payload->data->id,$payload->exp);
+        }catch (ExpiredException $e){
+            $response["status_code"] = 401;
+            $response["message"] = "token失效";
+            return response()->json($response);
+        } catch (\Exception $e){
+            $response["status_code"] = 401;
+            $response["message"] = "token非法";
+            return response()->json($response);
+        }
+        Auth::setUser($user);
+        return $next($request);
+    }
+}

+ 1 - 1
app/Http/Middleware/DecodingRequest.php

@@ -18,7 +18,7 @@ class DecodingRequest
     {
         if ($request->method() == "GET"){
             foreach ($request->input() as $key => $value){
-                if ($value != null)$request->offsetSet($key, urldecode($value));
+                if ($value != null && is_string($value))$request->offsetSet($key, urldecode($value));
             }
         }
         return $next($request);

+ 6 - 11
app/Http/Middleware/LogPostRequest.php

@@ -19,17 +19,12 @@ class LogPostRequest
      */
     public function handle($request, Closure $next)
     {
-        try {
-            if($request->method()!='GET'){
-                LogService::log($request->fullUrl(),$request->method(),
-                    '请求:'.json_encode($request->all())
-                    .'请求头:'.json_encode($request->headers->all())
-                );
-            }
-            return $next($request);
-        }catch (\Exception $e){
-            $this->push(__METHOD__."->".__LINE__,"路径跳转捕获",$e->getMessage()."  请求用户:".Auth::id()."  request对象:".json_encode($request));
-            return view("exception.404");
+        if($request->method()!='GET'){
+            LogService::log($request->fullUrl(),$request->method(),
+                '请求:'.json_encode($request->all())
+                .'请求头:'.json_encode($request->headers->all())
+            );
         }
+        return $next($request);
     }
 }

+ 30 - 0
app/Http/Requests/Printer/TerminalPrinterRequest.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Http\Requests\Printer;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class TerminalPrinterRequest extends FormRequest
+{
+    /**
+     * Determine if the user is authorized to make this request.
+     *
+     * @return bool
+     */
+    public function authorize(): bool
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array
+     */
+    public function rules(): array
+    {
+        return [
+            //
+        ];
+    }
+}

+ 24 - 0
app/Http/Requests/Printer/TerminalRequest.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Requests\Printer;
+
+use App\Traits\RequestApiFormValidation;
+use Illuminate\Foundation\Http\FormRequest;
+
+class TerminalRequest extends FormRequest
+{
+    use RequestApiFormValidation;
+
+
+    public function authorize(): bool
+    {
+        return true;
+    }
+
+    public function rules(): array
+    {
+        return [
+
+        ];
+    }
+}

+ 10 - 6
app/Http/Requests/RequirementRequest.php

@@ -3,20 +3,24 @@
 namespace App\Http\Requests;
 
 
-class RequirementRequest extends Request
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Gate;
+
+class RequirementRequest extends FormRequest
 {
     public function rules()
     {
-        switch($this->method())
-        {
+        switch ($this->method()) {
             case 'POST':
             case 'PUT':
             case 'PATCH':
             {
+                $score = '';
+                if (Gate::allows('需求发布-新建-直接发布')) $score = 'required|numeric';
                 return [
-                    'content'       => 'required|min:3',
-                    'title'       => 'required|min:3',
-                    'score' => 'required|numeric',
+                    'content' => 'required|min:3',
+                    'title' => 'required|min:3',
+                    'score' => $score,
                 ];
             }
             case 'GET':

+ 49 - 31
app/Jobs/CacheShelfTaskJob.php

@@ -4,6 +4,7 @@ namespace App\Jobs;
 
 use App\Components\ErrorPush;
 use App\Services\ForeignHaiRoboticsService;
+use App\Services\LogService;
 use App\Station;
 use App\StationTaskMaterialBox;
 use App\TaskTransaction;
@@ -15,6 +16,7 @@ use Illuminate\Queue\InteractsWithQueue;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 
 class CacheShelfTaskJob implements ShouldQueue
 {
@@ -46,25 +48,31 @@ class CacheShelfTaskJob implements ShouldQueue
         switch ($this->key){
             case "CACHE_SHELF_AVAILABLE"://缓存架释放呼叫
                 //等待一定时间来合并同类请求至此
-                $available = Cache::get($this->key,function (){return [];});
-                if ($this->count!==count($available))return;
+                $available = Cache::get($this->key,0);
+                Log::debug("队列事务1",["当前数量:{$this->count}","缓存数量:$available"]);
+                if ($this->count!=$available)return;
+                Cache::forget($this->key); //无论是否开始分发 都清除本次缓存架的计数器
+                //获取可用缓存架
+                $stations = app("StationService")->getCacheShelf(true);
+                Log::debug("队列事务2",["可用缓存架:{$stations->count()}"]);
+                if ($stations->count()==0)break;
                 //检查事务 尝试分发任务 改变下方序列来控制分发顺序 逐级分发 一次成功就终止
-                if ($this->dispatchOutTask($available,$service))break; //首先尝试向出库事务分发 分发成功跳出
-                if ($this->dispatchInTask($available,$service))break;  //尝试向入库事务分发
+                if ($this->dispatchOutTask($stations,$service))break; //首先尝试向出库事务分发 分发成功跳出
+                if ($this->dispatchInTask($stations,$service))break;  //尝试向入库事务分发
                 break;
             default://入库呼叫
                 if (!Cache::has($this->key))return;
                 /** @var Collection $task */
                 list($task,$location) = Cache::get($this->key);
-                if ($this->count!==$task->count())return;
+                if ($this->count!=$task->count())return;
                 $dataToPost = $service->makeJson_move_multi($task, '缓存架入立架', $location);
                 $controlSuccess = $service->controlHaiRobot($dataToPost,$task,'缓存架入立架');
                 $tIds = [];
                 $task->each(function ($t)use(&$tIds){$tIds[] = $t->id;});
-                StationTaskMaterialBox::query()->where("id",$tIds)
+                StationTaskMaterialBox::query()->whereIn("id",$tIds)
                     ->where("status","待处理")->update(['status' => $controlSuccess ? '处理中' : '异常']);
                 Cache::forget($this->key);
-                if ($controlSuccess)$this->materialBoxMappingCacheShelf($task,$location);
+                //if ($controlSuccess)$this->materialBoxMappingCacheShelf($task,$location);
         }
     }
 
@@ -88,11 +96,11 @@ class CacheShelfTaskJob implements ShouldQueue
     /**
      * 分发出库任务
      *
-     * @param array $available
+     * @param $stations
      * @param $service
      * @return bool
      */
-    private function dispatchOutTask(array $available, $service):bool
+    private function dispatchOutTask(&$stations,$service):bool
     {
         DB::beginTransaction();
         try {
@@ -101,14 +109,18 @@ class CacheShelfTaskJob implements ShouldQueue
                     $query->where("status","待处理");
                 })->where("status",3)->lockForUpdate()
                 ->where("mark",2)->groupBy("task_id")->get(); //检索等待的队列事务来获取对应任务
-            if ($this->dispatchTask($tasks,$available,$service,function ($obj,$stationId,$time,&$updateTransaction){
+            Log::debug("队列事务3",["队列出库任务:{$tasks->count()}"]);
+            if ($tasks->count()==0)return false;
+            if ($this->dispatchTask($tasks,$stations,$service,function ($obj,$stationId,$time,&$updateTransaction){
                 if ($obj->ids!=$obj->id){
                     $ids = explode(",",$obj->ids);
                     foreach ($ids as $id)$updateTransaction[] = ["id"=>$id,"to_station_id"=>$stationId,"status"=>0,"updated_at"=>$time];
                 }else $updateTransaction[] = ["id"=>$obj->id,"to_station_id"=>$stationId,"status"=>0,"updated_at"=>$time];
             },function ($service,$toLocation,$task,$prefix){
-                return $service->fetchGroup_multiLocation($toLocation,$task,$prefix,'立架出至缓存架',20);
-            },"to_station_id")){DB::commit();return true;}
+                return $service->fetchGroup_multiLocation($toLocation,$task,$prefix,'立架出至缓存架',20,false);
+            },"to_station_id")){
+                Log::debug("队列事务4",["缓存架剩余数量:{$stations->count()}"]);
+                DB::commit();return $stations->count()==0;} //缓存架用完 跳出,否则接着分发
             DB::rollBack();
         }catch (\Exception $e){
             DB::rollBack();
@@ -120,11 +132,11 @@ class CacheShelfTaskJob implements ShouldQueue
     /**
      * 分发入库任务
      *
-     * @param array $available
+     * @param $stations
      * @param $service
      * @return bool
      */
-    private function dispatchInTask(array $available, $service):bool
+    private function dispatchInTask(&$stations,$service):bool
     {
         DB::beginTransaction();
         try {
@@ -133,11 +145,16 @@ class CacheShelfTaskJob implements ShouldQueue
                     $query->where("status","待处理");
                 })->where("status",3)->lockForUpdate()
                 ->where("mark",1)->get(); //检索等待的队列事务来获取对应任务
-            if ($this->dispatchTask($tasks,$available,$service,function ($obj,$stationId,$time,&$updateTransaction){
+            Log::debug("队列事务3",["队列入库任务:{$tasks->count()}"]);
+            if ($tasks->count()==0)return false;
+            if ($this->dispatchTask($tasks,$stations,$service,function ($obj,$stationId,$time,&$updateTransaction){
                 $updateTransaction[] = ["id"=>$obj->id,"fm_station_id"=>$stationId,"status"=>0,"updated_at"=>$time];
             },function ($service,$toLocation,$task,$prefix){
-                return $service->fetchGroup_multiLocation($toLocation,$task,'','立架出至缓存架');
-            },"fm_station_id")){DB::commit();return true;}
+                return $service->fetchGroup_multiLocation($toLocation,$task,'','立架出至缓存架',20,false);
+            },"fm_station_id")){
+                Log::debug("队列事务5",["缓存架剩余数量:{$stations->count()}"]);
+                DB::commit();return $stations->count()==0; //缓存架用完 跳出,否则接着分发
+            }
             DB::rollBack();
         }catch (\Exception $e){
             DB::rollBack();
@@ -146,33 +163,34 @@ class CacheShelfTaskJob implements ShouldQueue
         return false;
     }
 
-    private function dispatchTask(\Illuminate\Database\Eloquent\Collection $tasks, array $available, $service,
+    private function dispatchTask(\Illuminate\Database\Eloquent\Collection $tasks,&$stations, $service,
                                   \Closure $update, \Closure $execute, string $stationName):bool
     {
-        if (!$tasks->count())return false;
-        if ($tasks->count()>count($available))$tasks = $tasks->slice(0,count($available));//事务过多切割部分处理
+        $locations = $stations;
+        if ($tasks->count()>$locations->count())$tasks = $tasks->slice(0,$locations->count());//事务过多切割部分处理
+        if ($tasks->count()<$locations->count()){
+            $stations = $stations->slice($tasks->count());
+            $stations = $stations->values($stations);
+        }
         $toLocation = collect();
         $task = collect();
-        $availableTemp = array_keys($available);
-        $map = app("StationService")->getStationMapping($availableTemp);//获取库位映射信息
         $updateTask = [["id","station_id","updated_at"]];
         $updateTransaction = [["id",$stationName,"status","updated_at"]];
         $time = date("Y-m-d H:i:s");
+        $map = [];
         foreach ($tasks as $index=>$obj){
-            $loc = $availableTemp[$index];
-            $toLocation->push($loc);
-            $obj->task->station_id = $map[$loc];
+            $toLocation->push($stations[$index]->code);
+            $map[$stations[$index]->code] = $stations[$index]->id;
+            $obj->task->station_id = $stations[$index]->id;
             $task->push($obj->task);
-            unset($available[$loc]);
-            $updateTask[] = ["id"=>$obj->task->id,"station_id"=>$map[$loc],"updated_at"=>$time];
-            $update($obj,$map[$loc],$time,$updateTransaction);
+            $updateTask[] = ["id"=>$obj->task->id,"station_id"=>$stations[$index]->id,"updated_at"=>$time];
+            $update($obj,$stations[$index]->id,$time,$updateTransaction);
         }
         app("BatchUpdateService")->batchUpdate("station_task_material_boxes",$updateTask);
         app("BatchUpdateService")->batchUpdate("task_transactions",$updateTransaction);
-        if ($execute($service,$toLocation,$task,$tasks[0]->station_task_batch_id)){
-            Cache::forever($this->key,$available);
+        if ($execute($service,$toLocation,$task,$tasks[0]->station_task_batch_id ?: '')){
             foreach ($toLocation as $value){
-                app("CacheShelfService")->lightUp($value,'3','0');
+                app("CacheShelfService")->lightUp($value,'3','0',["title"=>"机器人取箱中,禁止操作"]);
                 Cache::forever("CACHE_SHELF_OCCUPANCY_{$map[$value]}",true);
             }
             app("StationService")->locationOccupyMulti($toLocation->toArray());

+ 11 - 9
app/Jobs/SettlementBillReportTask.php

@@ -26,16 +26,18 @@ class SettlementBillReportTask implements ShouldQueue
     public $maxExceptions = 3;
 
     public $tries = 2;
+
+    public $init_date;
+
     /**
-     * Create a new job instance.
-     *
-     * @return void
+     * @param $init_date
      */
-    public function __construct()
+    public function __construct($init_date)
     {
-        //
+        $this->init_date = $init_date;
     }
 
+
     /**
      * Execute the job.
      *
@@ -46,21 +48,21 @@ class SettlementBillReportTask implements ShouldQueue
         //快递
         /** @var OwnerLogisticFeeReportService $expressFeeReportService */
         $expressFeeReportService = app('OwnerLogisticFeeReportService');
-        $expressFeeReportService->recordReport();
+        $expressFeeReportService->recordReport($this->init_date);
 
         //入库
         /** @var OwnerStoreFeeReportService $storeFeeReportService */
         $storeFeeReportService = app('OwnerStoreFeeReportService');
-        $storeFeeReportService->recordReport();
+        $storeFeeReportService->recordReport($this->init_date);
 
         //出库
         /** @var OwnerStoreOutFeeReportService $storeOutFeeReportService */
         $storeOutFeeReportService = app('OwnerStoreOutFeeReportService');
-        $storeOutFeeReportService->recordReport();
+        $storeOutFeeReportService->recordReport($this->init_date);
 
         //总账单
         /** @var OwnerFeeTotalService $feeTotal */
         $feeTotal = app('OwnerFeeTotalService');
-        $feeTotal->record();
+        $feeTotal->record($this->init_date);
     }
 }

+ 2 - 1
app/Jobs/WeightUpdateInstantBill.php

@@ -7,6 +7,7 @@ use App\OrderPackage;
 use App\Services\OrderService;
 use Illuminate\Bus\Queueable;
 use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Foundation\Bus\Dispatchable;
 use Illuminate\Queue\InteractsWithQueue;
 
@@ -19,7 +20,7 @@ class WeightUpdateInstantBill implements ShouldQueue
     /**
      * Create a new job instance.
      *
-     * @param OrderPackage|null $package
+     * @param OrderPackage|null|Model $package
      *
      * @return void
      */

+ 1 - 1
app/Listeners/UpdateOrderPackageExceptionListener.php

@@ -33,7 +33,7 @@ class UpdateOrderPackageExceptionListener implements ShouldQueue
                 $status = '返回派件';
                 break;
             case 2:
-                $status = '已收';
+                $status = '已收';
                 break;
             default:
                 $status = '无';

+ 34 - 0
app/Logging/CriticalFormatter.php

@@ -0,0 +1,34 @@
+<?php
+
+
+namespace App\Logging;
+
+
+use Monolog\Logger;
+
+/**
+ * Handler some critical,alert,emergency events
+ *
+ * Class CriticalFormatter
+ * @package App\Logging
+ */
+class CriticalFormatter
+{
+    public function __invoke($logger)
+    {
+        /** @var Logger $logger */
+        //$logger->popHandler();
+
+        //也可以在前置或后置设置一些通知渠道
+        //$logger->setHandlers([new EmailHandler()]); //TODO 这里设置处理器
+        //上面设置完处理器会覆盖原有处理器,原来的默认是流式写入(I/O磁盘)
+        $logger->setExceptionHandler(function ($e){
+            //比如 异常$e->getMessage()中存在Permission denied就是文件权限异常
+            //用switch捕获各种写入失败场景
+            //普通日志也应做此处理,记录应该分级分块
+            //logs表考虑下是否启用
+            //写入失败时,会再此处处理下
+        });
+    }
+
+}

+ 23 - 0
app/Logging/DebugFormatter.php

@@ -0,0 +1,23 @@
+<?php
+
+
+namespace App\Logging;
+
+use Monolog\Logger;
+
+/**
+ * Handle debug events
+ *
+ * Class DebugFormatter
+ * @package App\Logging
+ */
+class DebugFormatter
+{
+    /**
+     * @param Logger|\Illuminate\Log\Logger $logger
+     */
+    public function __invoke($logger)
+    {
+        //if (env("APP_ENV","production")!='local')$logger->popHandler();
+    }
+}

+ 34 - 0
app/Logging/ErrorFormatter.php

@@ -0,0 +1,34 @@
+<?php
+
+
+namespace App\Logging;
+
+
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Log;
+use Monolog\Logger;
+
+/**
+ * Handler error events
+ *
+ * Class ErrorFormatter
+ * @package App\Logging
+ */
+class ErrorFormatter
+{
+    /**
+     * @param Logger|\Illuminate\Log\Logger $logger
+     */
+    public function __invoke($logger)
+    {
+        $logger->setExceptionHandler(function ($e) {
+            if (stripos($e->getMessage(),"Permission denied")){
+                try {
+                    if (PHP_OS != 'WINNT')exec("chmod 777 ".base_path("storage/logs/error-".date("Y-m-d").".log"),$output,$return);
+                }catch (\Exception $e){
+                    Log::critical("日志写入错误",["msg"=>$e->getMessage(),"user"=>Auth::id()]);
+                }
+            }
+        });
+    }
+}

+ 16 - 0
app/Logging/Handler/EmailHandler.php

@@ -0,0 +1,16 @@
+<?php
+
+
+namespace App\Logging\Handler;
+
+
+use Monolog\Handler\AbstractProcessingHandler;
+
+class EmailHandler extends AbstractProcessingHandler
+{
+
+    protected function write(array $record): void
+    {
+        dump($record);
+    }
+}

+ 18 - 0
app/Logging/InfoFormatter.php

@@ -0,0 +1,18 @@
+<?php
+
+
+namespace App\Logging;
+
+/**
+ * Handle info events
+ *
+ * Class InfoFormatter
+ * @package App\Logging
+ */
+class InfoFormatter
+{
+    public function __invoke($logger)
+    {
+
+    }
+}

+ 18 - 0
app/Logging/WarningFormatter.php

@@ -0,0 +1,18 @@
+<?php
+
+
+namespace App\Logging;
+
+/**
+ * Handle some Notice,Warning events
+ *
+ * Class WarningFormatter
+ * @package App\Logging
+ */
+class WarningFormatter
+{
+    public function __invoke($logger)
+    {
+
+    }
+}

+ 1 - 1
app/OracleActAllocationDetails.php

@@ -22,7 +22,7 @@ class OracleActAllocationDetails extends Model
 
     public function oracleDocOrderHeader(): BelongsTo
     {
-        return $this->belongsTo('App\OracleDOCOrderHeader','orderno','orderno');
+        return $this->belongsTo(OracleDOCOrderHeader::class,'orderno','orderno');
     }
 
     public function oracleDocOrderSerialNos(): HasMany

+ 7 - 0
app/OracleDOCOrderHeader.php

@@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasMany;
 
 class OracleDOCOrderHeader extends Model
 {
@@ -67,10 +68,16 @@ class OracleDOCOrderHeader extends Model
         return $this->hasOne('App\OracleBasCode','code','ordertype')->where('codeid','SO_TYP');
     }
 
+    public function docOrderDeliveryInfo(): HasMany
+    {
+        return $this->hasMany(OracleDocOrderDeliveryInfo::class,'orderno','orderno');
+    }
+
     public function oracleDOCWaveDetail(): BelongsTo
     {
         return $this->belongsTo(OracleDOCWaveDetails::class,'orderno','orderno');
     }
+
     public function getLogistic()
     {
         /** @var LogisticService $logistic_service */

+ 46 - 0
app/OracleDocOrderDeliveryInfo.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class OracleDocOrderDeliveryInfo extends Model
+{
+    use ModelLogChanging;
+
+    use ModelLogChanging;
+
+    protected $connection = "oracle";
+    protected $table = "DOC_ORDER_DELIVERYINFO";
+    public $timestamps = false;
+
+    protected $fillable = [
+        'orderno','trackingno','userdefine1','userdefine3','userdefine4','userdefine5',
+        'formtransit','fromcode','formdepot',
+        'toransitcode','presorting','tocode',
+        'toroute','tocity','servicetype','UDF08','QRCODE'
+    ];
+
+    protected $casts = [
+        'userdefine1' => 'array',
+    ];
+
+    public function docOrderHeader(): BelongsTo
+    {
+        return $this->belongsTo(OracleDOCOrderHeader::class,'orderno','orderno');
+    }
+
+    /**
+     * OrderNo        订单单号
+     * TrackingNo     快递单号
+     * userDefine1    打印组件参数
+     * userDefine2    打印组件参数
+     * userDefine3    解码
+     * userDefine4    打印组件解析模板url
+     * userDefine5    打印版本
+     */
+
+}

+ 4 - 0
app/OracleInvLotLocId.php

@@ -24,4 +24,8 @@ class OracleInvLotLocId extends Model
     *         QTY 在库数量
     *         QtyAllocated 占用数量
     * */
+    public function oracleInvLotAtt(): \Illuminate\Database\Eloquent\Relations\BelongsTo
+    {
+       return $this->belongsTo(OracleInvLotAtt::class,'lotnum','lotnum');
+    }
 }

+ 6 - 0
app/Order.php

@@ -5,6 +5,7 @@ namespace App;
 use App\Traits\ModelTimeFormat;
 use Illuminate\Database\Eloquent\Model;
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
 class Order extends Model
 {
@@ -178,4 +179,9 @@ class Order extends Model
         ];
         return $arr[$string] ?? '否';
     }
+
+    public function OracleDOCOrderHeader(): BelongsTo
+    {
+        return $this->belongsTo(OracleDOCOrderHeader::class,'code','orderno');
+    }
 }

+ 7 - 2
app/OrderIssue.php

@@ -3,6 +3,7 @@
 namespace App;
 
 use App\Traits\ModelTimeFormat;
+use Illuminate\Support\Facades\Gate;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
@@ -52,7 +53,7 @@ class OrderIssue extends Model
      */
     protected $appends = [];
 
-    public function order(): \Illuminate\Database\Eloquent\Relations\BelongsTo
+    public function order(): BelongsTo
     {
         return $this->belongsTo(Order::class, 'order_id', 'id');
     }
@@ -292,7 +293,11 @@ class OrderIssue extends Model
     public function scopeJsonWith($query)
     {
         return $query->with(['issueType', 'logs' => function ($query){
-            $query->with('user')->orderByDesc('created_at');
+            if (Gate::denies('订单管理-问题件-客户不可见')){
+                $query->with('user')->orderByDesc('created_at');
+            } else{
+                $query->with('user')->where('tag','=',0)->orderByDesc('created_at');
+            }
         },'order'=>function($query){
             $query->with(['shop', 'logistic', 'owner', 'packages.commodities.commodity.barcodes']);
         },'secondOrder'=>function($query){

+ 6 - 3
app/OrderIssueProcessLog.php

@@ -6,6 +6,7 @@ use App\Traits\ModelTimeFormat;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasOne;
 
 class OrderIssueProcessLog extends Model
 {
@@ -14,12 +15,14 @@ class OrderIssueProcessLog extends Model
     //
     use ModelTimeFormat;
 
-    protected $fillable = ['order_issue_id','user_id','content','type'];
+    protected $fillable = ['order_issue_id','user_id','content','type','tag'];
 
-    public function orderIssue(){
+    public function orderIssue(): HasOne
+    {
         return $this->hasOne('App\OrderIssue','id','order_issue_id');
     }
-    public function user(){
+    public function user(): HasOne
+    {
         return $this->hasOne('App\User','id','user_id');
     }
 }

+ 226 - 146
app/OrderPackage.php

@@ -40,38 +40,90 @@ class OrderPackage extends Model
         'status',
         'sent_at',
         'received_at',
-        'exception',
         'transfer_status',
         'owner_id',
         'uploaded_to_wms',
-        'exception_type',
         'sync_routes_flag',
+        'is_manual_update',
     ];
 
-    public function order(){
-        return $this->belongsTo('App\Order','order_id','id');
-    }
-
     protected $casts = [
         'transfer_status' => 'array',
         'sync_routes_flag' => 'boolean',
+        'is_manual_update' => 'boolean',
+    ];
+
+    static public $enums = [
+        'status' => [
+            ''=>0,
+            '无'=>1,
+            '已称重'=>2,
+            '已揽收'=>3,
+            '揽件异常'=>4,
+            '疑似库内丢件'=>5,
+            '在途'=>6,
+            '在途异常'=>7,
+            '派送中'=>8,
+            '派送异常'=>9,
+            '返回中'=>10,
+            '返回异常'=>11,
+            '返回派件'=>12,
+            '其他异常'=>13,
+            '已签收'=>14,
+            '其他'=>14,
+        ],
     ];
 
+    function __construct(array $attributes = [])
+    {
+        foreach (self::$enums as &$enum) {
+            $enum=$enum+array_flip($enum);
+        }
+        parent::__construct($attributes);
+    }
+
+    public function getStatusAttribute($value)
+    {
+        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];
+    }
+
+    public static function switchStatus($value): int
+    {
+        if (!(self::$enums['status'][$value] ?? false))return 0;
+        return self::$enums['status'][$value];
+    }
+
+    public function order()
+    {
+        return $this->belongsTo('App\Order', 'order_id', 'id');
+    }
+
+
     public function commodities(): HasMany
     {
-        return $this->hasMany('App\OrderPackageCommodities','order_package_id','id');
+        return $this->hasMany('App\OrderPackageCommodities', 'order_package_id', 'id');
     }
+
     public function paperBox(): HasOne
     {
-        return $this->hasOne('App\PaperBox','id','paper_box_id');
+        return $this->hasOne('App\PaperBox', 'id', 'paper_box_id');
     }
+
     public function measuringMachine(): HasOne
     {
-        return $this->hasOne('App\MeasuringMachine','id','measuring_machine_id');
+        return $this->hasOne('App\MeasuringMachine', 'id', 'measuring_machine_id');
     }
+
     public function WMSReflectPackage(): HasOne
     {
-        return $this->hasOne('App\WMSReflectPackage','SOReference5','logistic_number');
+        return $this->hasOne('App\WMSReflectPackage', 'SOReference5', 'logistic_number');
     }
 
     static protected $oracleOrderHeaderFields = [
@@ -87,24 +139,31 @@ class OrderPackage extends Model
         'doc_wave_header.descr',
     ];
 
-    protected $tempFields=[
-        'temOracleInfo','temOwner','temLogistic',
+    protected $tempFields = [
+        'temOracleInfo', 'temOwner', 'temLogistic',
     ];
 
-    public function setLengthAttribute($value){
-        if(empty((int)($value)))return;
+    public function setLengthAttribute($value)
+    {
+        if (empty((int)($value))) return;
         $this->attributes['length'] = $value;
     }
-    public function setWidthAttribute($value){
-        if(empty((int)($value)))return;
+
+    public function setWidthAttribute($value)
+    {
+        if (empty((int)($value))) return;
         $this->attributes['width'] = $value;
     }
-    public function setHeightAttribute($value){
-        if(empty((int)($value)))return;
+
+    public function setHeightAttribute($value)
+    {
+        if (empty((int)($value))) return;
         $this->attributes['height'] = $value;
     }
-    public function setBulkAttribute($value){
-        if(empty((int)($value)))return;
+
+    public function setBulkAttribute($value)
+    {
+        if (empty((int)($value))) return;
         $this->attributes['bulk'] = $value;
     }
 
@@ -113,196 +172,212 @@ class OrderPackage extends Model
         $this->commodities()->delete();
         return parent::delete();
     }
-    public function deleteSafe(){
+
+    public function deleteSafe()
+    {
         return parent::delete();
     }
 
-    public function isActivityBatch(){
-        return ($this['batch_rule'] && strstr($this['batch_rule'],'组合')  && $this['batch_number'] );
+    public function isActivityBatch()
+    {
+        return ($this['batch_rule'] && strstr($this['batch_rule'], '组合') && $this['batch_number']);
     }
-    public function fetchAllFromOracle(){
-        if(empty($this->oracleInfo))return null;
-/*        $this->fetchOwnerFromOracle();
-        $this->fetchLogisticFromOracle();*/
-/*        $this['recipient'] = $this->oracleInfo['consigneename'];
-        $this['order_code'] = $this->oracleInfo['orderno'];*/
+
+    public function fetchAllFromOracle()
+    {
+        if (empty($this->oracleInfo)) return null;
+        /*        $this->fetchOwnerFromOracle();
+                $this->fetchLogisticFromOracle();*/
+        /*        $this['recipient'] = $this->oracleInfo['consigneename'];
+                $this['order_code'] = $this->oracleInfo['orderno'];*/
         $this['batch_rule'] = $this->oracleInfo['descr'];
-/*        $this['recipient_mobile'] = $this->oracleInfo['c_tel2']??$this->oracleInfo['c_tel1'];
-        if(!$this['logistic_number']&&$this->oracleInfo['soreference5'])
-            $this['logistic_number'] = $this->oracleInfo['soreference5'];*/
-        $this['batch_number'] = $this->oracleInfo['waveno']??null;
+        /*        $this['recipient_mobile'] = $this->oracleInfo['c_tel2']??$this->oracleInfo['c_tel1'];
+                if(!$this['logistic_number']&&$this->oracleInfo['soreference5'])
+                    $this['logistic_number'] = $this->oracleInfo['soreference5'];*/
+        $this['batch_number'] = $this->oracleInfo['waveno'] ?? null;
     }
-    static public function createPackagesFromBatchCode($batchCode,$weight){
 
+    static public function createPackagesFromBatchCode($batchCode, $weight)
+    {
 
 
-        $queryBuilder=OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields);
-        $queryBuilder->where('doc_order_header.waveno',$batchCode);
-        $queryBuilder->leftJoin('act_allocation_details','act_allocation_details.orderno','doc_order_header.orderno');
-        $queryBuilder->leftJoin('doc_wave_header','doc_wave_header.waveno','doc_order_header.waveno');
-        $resultOracleObjs=$queryBuilder->get();
-        $resultOracleObjs_grouped=$resultOracleObjs->groupBy('soreference5');
+        $queryBuilder = OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields);
+        $queryBuilder->where('doc_order_header.waveno', $batchCode);
+        $queryBuilder->leftJoin('act_allocation_details', 'act_allocation_details.orderno', 'doc_order_header.orderno');
+        $queryBuilder->leftJoin('doc_wave_header', 'doc_wave_header.waveno', 'doc_order_header.waveno');
+        $resultOracleObjs = $queryBuilder->get();
+        $resultOracleObjs_grouped = $resultOracleObjs->groupBy('soreference5');
         $packages = [];
         $now = Carbon::now();
 
-        foreach($resultOracleObjs_grouped as $resultOracleObj_grouped){
+        foreach ($resultOracleObjs_grouped as $resultOracleObj_grouped) {
             $resultOracleObj = $resultOracleObj_grouped[0];
-            /** @var OrderService $orderService*/
+            /** @var OrderService $orderService */
             $orderService = app('OrderService');
             $order = $orderService->logisticNumberFirstOrCreateOrder($resultOracleObj['soreference5']);
-            if (!$order){
-                app('LogService')->log(__METHOD__,"此包裹在WMS未找到order",json_encode($resultOracleObj),Auth::user()['id']);
+            if (!$order) {
+                app('LogService')->log(__METHOD__, "此包裹在WMS未找到order", json_encode($resultOracleObj), Auth::user()['id']);
                 continue;
             }
-            array_push($packages,[
-                'batch_number'=>$batchCode??'',
+            array_push($packages, [
+                'batch_number' => $batchCode ?? '',
                 'order_id' => $order->id,
-                'logistic_number'=>$resultOracleObj['soreference5']??'',
-                'weight'=>$weight,
-                'weighed_at'=> $now,
-                'uploaded_to_wms'=>"是",
-                "created_at"=>$now,
+                'logistic_number' => $resultOracleObj['soreference5'] ?? '',
+                'weight' => $weight,
+                'weighed_at' => $now,
+                'uploaded_to_wms' => "是",
+                "created_at" => $now,
             ]);
         }
 
 
         $packagesLogisticNumbers = array_map(function ($orderPackage) {
             return $orderPackage['logistic_number'];
-        } ,$packages);
-        $existingOrderPackages=OrderPackage::whereIn('logistic_number', $packagesLogisticNumbers)->get();
-        $existingLogisticNumbers=$existingOrderPackages->map(function($orderPackage){
+        }, $packages);
+        $existingOrderPackages = OrderPackage::whereIn('logistic_number', $packagesLogisticNumbers)->get();
+        $existingLogisticNumbers = $existingOrderPackages->map(function ($orderPackage) {
             return $orderPackage['logistic_number'];
         })->toArray();
         OrderPackage::whereIn('logistic_number', $existingLogisticNumbers)->update([
-            'batch_number'=>$batchCode??'',
-            'weight'=>$weight,
-            'weighed_at'=> $now,
-            'uploaded_to_wms'=>"是",]);
-        $newPackages=$packages;
-        if($existingOrderPackages->isNotEmpty())
-            $newPackages=array_filter($packages,function ($package)use($existingLogisticNumbers){
-                return array_search($package['logistic_number'],$existingLogisticNumbers)===false;
+            'batch_number' => $batchCode ?? '',
+            'weight' => $weight,
+            'weighed_at' => $now,
+            'uploaded_to_wms' => "是",]);
+        $newPackages = $packages;
+        if ($existingOrderPackages->isNotEmpty())
+            $newPackages = array_filter($packages, function ($package) use ($existingLogisticNumbers) {
+                return array_search($package['logistic_number'], $existingLogisticNumbers) === false;
             });
-        DB::transaction(function ()use($newPackages){
+        DB::transaction(function () use ($newPackages) {
             OrderPackage::query()->insert($newPackages);
         });
 
 
-        app('LogService')->log(__METHOD__,"批量录入包裹成功",json_encode($packages),Auth::user()['id']);
+        app('LogService')->log(__METHOD__, "批量录入包裹成功", json_encode($packages), Auth::user()['id']);
     }
-    public function unifyThisMeasureUnderSameBatch(){
+
+    public function unifyThisMeasureUnderSameBatch()
+    {
         $this->fetchPaperBox();
-        $params=[];
-        !empty($this['weight'])?$params['weight']= $this['weight']:null;
-        !empty($this['length'])?$params['length']= $this['length']:null;
-        !empty($this['width'])?$params['width']= $this['width']:null;
-        !empty($this['height'])?$params['height']= $this['height']:null;
-        !empty($this['bulk'])?$params['bulk']= $this['bulk']:null;
-        !empty($this['measuring_machine_id'])?$params['measuring_machine_id']= $this['measuring_machine_id']:null;
-        !empty($this['weighed_at'])?$params['weighed_at']= $this['weighed_at']:null;
-        !empty($this['paper_box_id'])?$params['paper_box_id']= $this['paper_box_id']:null;
-        if(empty($params)||empty($this['batch_number']))return;
-        OrderPackage::query()->where(['batch_number'=>$this['batch_number']])->update($params);
+        $params = [];
+        !empty($this['weight']) ? $params['weight'] = $this['weight'] : null;
+        !empty($this['length']) ? $params['length'] = $this['length'] : null;
+        !empty($this['width']) ? $params['width'] = $this['width'] : null;
+        !empty($this['height']) ? $params['height'] = $this['height'] : null;
+        !empty($this['bulk']) ? $params['bulk'] = $this['bulk'] : null;
+        !empty($this['measuring_machine_id']) ? $params['measuring_machine_id'] = $this['measuring_machine_id'] : null;
+        !empty($this['weighed_at']) ? $params['weighed_at'] = $this['weighed_at'] : null;
+        !empty($this['paper_box_id']) ? $params['paper_box_id'] = $this['paper_box_id'] : null;
+        if (empty($params) || empty($this['batch_number'])) return;
+        OrderPackage::query()->where(['batch_number' => $this['batch_number']])->update($params);
     }
-    public function fetchLogisticFromOracle(){
-        if(empty($this->oracleInfo))return null;
-        if(Arr::exists($this->tempFields,'temLogistic'))return $this->tempFields['temLogistic'];
-        Controller::logs(__METHOD__, __FUNCTION__, "tempPackage:{$this->oracleInfo['carrierid']}||SOR:{$this->oracleInfo['SOReference5']}||sor:{$this->oracleInfo['soreference5']}||orderno:{$this['orderno']}" , null);
-        if(!$this->oracleInfo['carrierid'])return null;
-        $logistic= Logistic::query()->where('code',$this->oracleInfo['carrierid'])->first();
-        if(!$logistic){
-            $logistic=Logistic::query()->create(['code'=>$this->oracleInfo['carrierid'],'name'=>$this->oracleInfo['carrierid']]);
-            Controller::logs(__METHOD__, __FUNCTION__, "富勒下发找不到快递公司,添加{$this->oracleInfo['carrierid']}" , null);
+
+    public function fetchLogisticFromOracle()
+    {
+        if (empty($this->oracleInfo)) return null;
+        if (Arr::exists($this->tempFields, 'temLogistic')) return $this->tempFields['temLogistic'];
+        Controller::logs(__METHOD__, __FUNCTION__, "tempPackage:{$this->oracleInfo['carrierid']}||SOR:{$this->oracleInfo['SOReference5']}||sor:{$this->oracleInfo['soreference5']}||orderno:{$this['orderno']}", null);
+        if (!$this->oracleInfo['carrierid']) return null;
+        $logistic = Logistic::query()->where('code', $this->oracleInfo['carrierid'])->first();
+        if (!$logistic) {
+            $logistic = Logistic::query()->create(['code' => $this->oracleInfo['carrierid'], 'name' => $this->oracleInfo['carrierid']]);
+            Controller::logs(__METHOD__, __FUNCTION__, "富勒下发找不到快递公司,添加{$this->oracleInfo['carrierid']}", null);
         }
-        Controller::logs(__METHOD__, __FUNCTION__, "tempPackage2:{$logistic->id}" , null);
-        if(!$logistic)return null;
-        $this->tempFields['temLogistic']=$logistic;
+        Controller::logs(__METHOD__, __FUNCTION__, "tempPackage2:{$logistic->id}", null);
+        if (!$logistic) return null;
+        $this->tempFields['temLogistic'] = $logistic;
         $this['logistic_id'] = $logistic['id'];
         return $logistic;
     }
-    public function fetchOwnerFromOracle(){
-        if(empty($this->oracleInfo))return null;
-        if(Arr::exists($this->tempFields,'temOwner'))return $this->tempFields['temOwner'];
-        $owner= Owner::query()->where('code',$this->oracleInfo['customerid'])->first();
-        if(!$owner){
-            $owner=Owner::query()->create(['code'=>$this->oracleInfo['customerid'],'name'=>$this->oracleInfo['customerid']]);
-            Controller::logs(__METHOD__, __FUNCTION__, "富勒下发找不到货主,添加{$this->oracleInfo['customerid']}" , null);
+
+    public function fetchOwnerFromOracle()
+    {
+        if (empty($this->oracleInfo)) return null;
+        if (Arr::exists($this->tempFields, 'temOwner')) return $this->tempFields['temOwner'];
+        $owner = Owner::query()->where('code', $this->oracleInfo['customerid'])->first();
+        if (!$owner) {
+            $owner = Owner::query()->create(['code' => $this->oracleInfo['customerid'], 'name' => $this->oracleInfo['customerid']]);
+            Controller::logs(__METHOD__, __FUNCTION__, "富勒下发找不到货主,添加{$this->oracleInfo['customerid']}", null);
         }
-        if(!$owner)return null;
-        $this->tempFields['temOwner']=$owner;
+        if (!$owner) return null;
+        $this->tempFields['temOwner'] = $owner;
         $this['owner_id'] = $owner['id'];
         return $owner;
     }
+
     //寻找相近纸箱ID
-    public  function fetchPaperBox($max=null, $centre=null, $min=null, $owner_id=null){
-        if($this['paper_box_id'])return $this['paper_box_id'];
-        $sumDiffer=0;
-        $maxDiffer=0;
-        $paperBox_id=null;
-        if(!$max)$max=$this['length'];
-        if(!$centre)$centre=$this['width'];
-        if(!$min)$min=$this['height'];
-        if(!$owner_id) $owner_id = $this['order'] ? $this['order']['owner_id'] : null;
-        if(!$owner_id) {
+    public function fetchPaperBox($max = null, $centre = null, $min = null, $owner_id = null)
+    {
+        if ($this['paper_box_id']) return $this['paper_box_id'];
+        $sumDiffer = 0;
+        $maxDiffer = 0;
+        $paperBox_id = null;
+        if (!$max) $max = $this['length'];
+        if (!$centre) $centre = $this['width'];
+        if (!$min) $min = $this['height'];
+        if (!$owner_id) $owner_id = $this['order'] ? $this['order']['owner_id'] : null;
+        if (!$owner_id) {
             $owner = $this->fetchOwnerFromOracle();
             $owner_id = $owner['id'];
-            if(!$owner_id)return null;
+            if (!$owner_id) return null;
         }
-        $boxes=Owner::select('id')->with('paperBoxes')->find($owner_id);
-        $targetPaperBox=null;
-        foreach ($boxes->paperBoxes as $i=>$paperBox){
-            if ($paperBox->length==$max&&$paperBox->width==$centre&&$paperBox->height==$min){
-                $targetPaperBox=$paperBox;
+        $boxes = Owner::select('id')->with('paperBoxes')->find($owner_id);
+        $targetPaperBox = null;
+        foreach ($boxes->paperBoxes as $i => $paperBox) {
+            if ($paperBox->length == $max && $paperBox->width == $centre && $paperBox->height == $min) {
+                $targetPaperBox = $paperBox;
                 break;
             }
-            $lengthDiffer=abs($paperBox->length-$max);
-            $widthDiffer=abs($paperBox->width-$centre);
-            $heightDiffer=abs($paperBox->height-$min);
-            $thisMaxDiffer=($lengthDiffer>=($widthDiffer>=$heightDiffer?$widthDiffer:$heightDiffer)?$lengthDiffer:($widthDiffer>=$heightDiffer?$widthDiffer:$heightDiffer));
-            if($i==0){
-                $maxDiffer=$thisMaxDiffer;
-                $sumDiffer=$lengthDiffer+$widthDiffer+$heightDiffer;
-                $targetPaperBox=$paperBox;
+            $lengthDiffer = abs($paperBox->length - $max);
+            $widthDiffer = abs($paperBox->width - $centre);
+            $heightDiffer = abs($paperBox->height - $min);
+            $thisMaxDiffer = ($lengthDiffer >= ($widthDiffer >= $heightDiffer ? $widthDiffer : $heightDiffer) ? $lengthDiffer : ($widthDiffer >= $heightDiffer ? $widthDiffer : $heightDiffer));
+            if ($i == 0) {
+                $maxDiffer = $thisMaxDiffer;
+                $sumDiffer = $lengthDiffer + $widthDiffer + $heightDiffer;
+                $targetPaperBox = $paperBox;
             }
-            if ($thisMaxDiffer==$maxDiffer){
-                if($sumDiffer>($lengthDiffer+$widthDiffer+$heightDiffer)){
-                    $sumDiffer=$lengthDiffer+$widthDiffer+$heightDiffer;
-                    $targetPaperBox=$paperBox;
+            if ($thisMaxDiffer == $maxDiffer) {
+                if ($sumDiffer > ($lengthDiffer + $widthDiffer + $heightDiffer)) {
+                    $sumDiffer = $lengthDiffer + $widthDiffer + $heightDiffer;
+                    $targetPaperBox = $paperBox;
                 }
             }
-            if ($thisMaxDiffer<$maxDiffer){
-                $sumDiffer=$lengthDiffer+$widthDiffer+$heightDiffer;
-                $maxDiffer=$thisMaxDiffer;
-                $targetPaperBox=$paperBox;
+            if ($thisMaxDiffer < $maxDiffer) {
+                $sumDiffer = $lengthDiffer + $widthDiffer + $heightDiffer;
+                $maxDiffer = $thisMaxDiffer;
+                $targetPaperBox = $paperBox;
             }
         }
-        if($targetPaperBox)$this['paper_box_id']=$targetPaperBox['id'];
+        if ($targetPaperBox) $this['paper_box_id'] = $targetPaperBox['id'];
         return $targetPaperBox['id'];
     }
+
     public function getOracleInfoAttribute()
     {
-        if(isset($this->tempFields['temOracleInfo']))return $this->tempFields['temOracleInfo'];
-        if(empty($this['logistic_number'])&&empty($this['order_code']))return '';
-        if($this['order_code']){
-            $resultOracleObjs=OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields)->where('orderno',$this['order_code']);
-            $resultOracleObjs->leftJoin('doc_wave_header','doc_wave_header.waveno','doc_order_header.waveno');
-        }else{
-            $resultOracleObjs=OracleActAllocationDetails::query()->select(self::$oracleOrderHeaderFields);
-            $resultOracleObjs->where('picktotraceid',$this['logistic_number']);
-            $resultOracleObjs->leftJoin('DOC_Order_Header','act_allocation_details.orderno','doc_order_header.orderno');
-            $resultOracleObjs->leftJoin('doc_wave_header','doc_wave_header.waveno','doc_order_header.waveno');
+        if (isset($this->tempFields['temOracleInfo'])) return $this->tempFields['temOracleInfo'];
+        if (empty($this['logistic_number']) && empty($this['order_code'])) return '';
+        if ($this['order_code']) {
+            $resultOracleObjs = OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields)->where('orderno', $this['order_code']);
+            $resultOracleObjs->leftJoin('doc_wave_header', 'doc_wave_header.waveno', 'doc_order_header.waveno');
+        } else {
+            $resultOracleObjs = OracleActAllocationDetails::query()->select(self::$oracleOrderHeaderFields);
+            $resultOracleObjs->where('picktotraceid', $this['logistic_number']);
+            $resultOracleObjs->leftJoin('DOC_Order_Header', 'act_allocation_details.orderno', 'doc_order_header.orderno');
+            $resultOracleObjs->leftJoin('doc_wave_header', 'doc_wave_header.waveno', 'doc_order_header.waveno');
         }
-        $this->tempFields['temOracleInfo']=$resultOracleObjs->first();
-        if(empty($this->tempFields['temOracleInfo'])) {
-            $resultOracleObjs=OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields)->where('soreference5',$this['logistic_number']);
-            $resultOracleObjs->leftJoin('doc_wave_header','doc_wave_header.waveno','doc_order_header.waveno');
+        $this->tempFields['temOracleInfo'] = $resultOracleObjs->first();
+        if (empty($this->tempFields['temOracleInfo'])) {
+            $resultOracleObjs = OracleDOCOrderHeader::query()->select(self::$oracleOrderHeaderFields)->where('soreference5', $this['logistic_number']);
+            $resultOracleObjs->leftJoin('doc_wave_header', 'doc_wave_header.waveno', 'doc_order_header.waveno');
         }
-        $this->tempFields['temOracleInfo']=$resultOracleObjs->first();
+        $this->tempFields['temOracleInfo'] = $resultOracleObjs->first();
         return $this->tempFields['temOracleInfo'];
     }
+
     public function getLogisticNumberAttribute($val)
     {
-        if(strpos($val,'null')!==false)return '';
+        if (strpos($val, 'null') !== false) return '';
         return $val;
     }
 
@@ -320,4 +395,9 @@ class OrderPackage extends Model
     {
         return $this->hasMany(OrderPackageRemark::class);
     }
+
+    public function rejectedBill(): BelongsTo
+    {
+        return $this->belongsTo(RejectedBill::class, 'logistic_number', 'logistic_number_return');
+    }
 }

+ 26 - 0
app/OrderPackageExpressBillPrintRecords.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class OrderPackageExpressBillPrintRecord extends Model
+{
+    use ModelLogChanging;
+    protected $table = 'order_package_express_bill_print_records';
+
+    protected $fillable = ['order_id','order_package_id','process_id','logistic_number','print_count','task_id'];
+
+    public function order(): BelongsTo
+    {
+        return $this->belongsTo(Order::class);
+    }
+
+    public function orderPackage(): BelongsTo
+    {
+        return $this->belongsTo(OrderPackage::class);
+    }
+}

+ 2 - 1
app/Owner.php

@@ -39,7 +39,8 @@ class Owner extends Model
         'subjection',           //主体公司
         'is_tax_exist',         //是否必填税率
         'model_sequence',       //调箱序列(优先级匹配)
-        'is_check_asn'          //是否校验ASN(收货时检查此项)
+        'is_check_asn',          //是否校验ASN(收货时检查此项)
+        'owner_group_id',        // 所属组别
     ];
     //relevance说明 0:仓储 1:作业 2:快递 3:物流 4:直发 5:系统 存储示例:["0","1"]存在仓储与作业计费
     protected $casts = [

+ 20 - 0
app/OwnerGroup.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class OwnerGroup extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+    public $fillable = [
+        'name',                 //名称
+    ];
+
+
+}

+ 30 - 0
app/OwnerLogisticPrintTemplate.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class OwnerLogisticPrintTemplate extends Model
+{
+    use ModelLogChanging;
+    public $timestamps = false;
+    protected $fillable = ['owner_id','logistic_id','print_template_id'];
+
+    public function printTemplate(): BelongsTo
+    {
+        return $this->belongsTo(PrintTemplate::class);
+    }
+
+    public function owner():BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+
+    public function logistic():BelongsTo
+    {
+        return $this->belongsTo(Logistic::class);
+    }
+}

+ 25 - 0
app/PrintPartImage.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+
+class PrintPartImage extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable = ['name'];
+
+    public function file(): HasOne
+    {
+        return $this->hasOne(UploadFile::class,'table_id','id')->where('table_name','print_part_images');
+    }
+
+    public function saveFile($file,$fileName){
+        $fileSuffix=strtolower($file->getClientOriginalExtension());
+        return UploadFile::query()->updateOrCreate(['table_name' => $this->getTable(), 'table_id' => $this['id'], 'url' => '/files/'.$fileName, 'type' => $fileSuffix]);
+    }
+}

+ 11 - 0
app/PrintTemplate.php

@@ -5,10 +5,21 @@ namespace App;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasMany;
 
 class PrintTemplate extends Model
 {
     use ModelLogChanging;
 
     protected $fillable = ['name','value'];
+
+    protected $casts = [
+        'value' => 'array'
+    ];
+
+
+    public function ownerLogisticPrintTemplate(): HasMany
+    {
+        return $this->hasMany(OwnerLogisticPrintTemplate::class,'print_template_id','id');
+    }
 }

+ 86 - 46
app/Providers/AppServiceProvider.php

@@ -124,13 +124,14 @@ use App\Services\weight\HaoChuangWeightService;
 use App\Services\weight\HengLiWeightService;
 use App\Services\PrintPartService;
 use App\Services\PrintTemplateService;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Queue\Events\JobFailed;
 use Illuminate\Queue\Events\JobProcessed;
-use Illuminate\Queue\Events\JobProcessing;
 use Illuminate\Support\Facades\Queue;
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\Facades\View;
 use Illuminate\Support\ServiceProvider;
+use Laravel\Tinker\TinkerServiceProvider;
 use Ramsey\Uuid\Uuid;
 use Illuminate\Support\Facades\Validator;
 use App\Services\SupplierService;
@@ -141,11 +142,21 @@ use App\Services\ForeignZhenCangService;
 use App\Services\StorageService;
 use App\Services\LogisticAliJiSuApiService;
 use App\Services\CommodityMaterialBoxModelService;
+use App\Services\PrintService;
+use App\Services\TerminalService;
+use App\Services\TerminalPrinterService;
 use App\Services\OwnerLogisticFeeDetailService;
 use App\Services\OwnerLogisticFeeReportService;
 use App\Services\LogisticSyncRecordService;
 use App\Services\OwnerBillReportArchiveService;
 use App\Services\SettlementBillsAreaFeeService;
+use App\Services\PDDDeliveryService;
+use App\Services\TBDeliveryService;
+use App\Services\SFDeliveryService;
+use App\Services\JDDeliveryService;
+use App\Services\SFQHDDeliveryService;
+use App\Services\DeliveryService;
+use App\Services\PrintPartImageService;
 use App\Services\OwnerStoreFeeDetailService;
 use App\Services\OwnerStoreFeeReportService;
 use App\Services\OwnerStoreOutFeeDetailService;
@@ -161,6 +172,8 @@ use App\Services\SettlementIndemnityFeeService;
 use App\Services\DbOpenService;
 use App\Services\DeliveryTypeService;
 use App\Services\ErrorPushService;
+use App\Services\OrderPackageExpressBillPrintRecordService;
+use App\Services\TerminalPrinterLogisticService;
 use App\Services\MaterialBoxModelService;
 use App\Services\HandInStorageService;
 use App\Services\RequirementService;
@@ -168,6 +181,7 @@ use App\Services\RequirementUserService;
 use App\Services\WorkOrderService;
 use App\Services\WorkOrderTypeService;
 use App\Services\OrderPackageRemarkService;
+use App\Services\LaborCompanyService;
 
 class AppServiceProvider extends ServiceProvider
 {
@@ -187,51 +201,11 @@ class AppServiceProvider extends ServiceProvider
      */
     public function boot()
     {
-        $this->loadingService();
-        $this->registerObserver();
-        //
-        Schema::defaultStringLength(191);
-        Queue::failing(function (JobFailed $event) {
-            (new Controller())->log(__METHOD__, 'EventError_', json_encode($event));
-            $payload = $event->job->payload();
-            $displayName = $payload['displayName'];
-            //快递信息同步失败计数
-            /** @var  $logisticSyncRecordService  LogisticSyncRecordService*/
-            $logisticSyncRecordService = app("LogisticSyncRecordService");
-            if ($logisticSyncRecordService->isLogisticSyncJob($displayName)) {
-                $logisticSyncRecordService->logisticSyncRecord($displayName, 'failed_count');
-            }
-        });
-        //扩展身份证验证规则
-        Validator::extend('identity_cards', function($attribute, $value, $parameters) {
-            return preg_match('/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)/', $value);
-        });
-        View::share('pageUuid',Uuid::uuid4());
-
-        \Illuminate\Database\Query\Builder::macro('sql', function () {
-            $bindings = $this->getBindings();
-            $sql = str_replace('?',"'%s'",$this->toSql());
-            return vsprintf($sql, $bindings);
-        });
-
-        \Illuminate\Database\Eloquent\Builder::macro('sql', function(){
-            return ($this->getQuery()->sql());
-        });
-
-        Queue::before(function (JobProcessing $event) {
-
-        });
-        //任务成功后的回调
-        Queue::after(function (JobProcessed $event) {
-            //快递信息同步成功计数
-            $payload = $event->job->payload();
-            $displayName = $payload['displayName'];
-            /** @var  $logisticSyncRecordService  LogisticSyncRecordService*/
-            $logisticSyncRecordService = app("LogisticSyncRecordService");
-            if ($logisticSyncRecordService->isLogisticSyncJob($displayName)) {
-                $logisticSyncRecordService->logisticSyncRecord($displayName, 'succeed_count');
-            }
-        });
+        $this->loadingService();    //加载服务
+        $this->registerObserver();  //注册监听器
+        $this->registerProvider();  //注册可选择的服务提供者
+        $this->appendExtension();   //追加扩展
+        $this->someTask();          //一些任务
     }
 
     private function loadingService(){
@@ -253,6 +227,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('DataHandlerService',DataHandlerService::class);
         app()->singleton('DbOpenService',DbOpenService::class);
         app()->singleton('DeliveryAppointmentService',DeliveryAppointmentService::class);
+        app()->singleton('DeliveryService',DeliveryService::class);
         app()->singleton('DeliveryTypeService',DeliveryTypeService::class);
         app()->singleton('DemandProcessService',DemandProcessService::class);
         app()->singleton('DemandService',DemandService::class);
@@ -271,6 +246,8 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('InventoryAccountMissionService',InventoryAccountMissionService::class);
         app()->singleton('InventoryCompareService', InventoryCompareService::class);
         app()->singleton('InventoryDailyLogService', InventoryDailyLogService::class);
+        app()->singleton('JDDeliveryService',JDDeliveryService::class);
+        app()->singleton('LaborCompanyService',LaborCompanyService::class);
         app()->singleton('LaborReportsCountingRecordService', LaborReportsCountingRecordService::class);
         app()->singleton('LogService', LogService::class);
         app()->singleton('LogisticAliJiSuApiService',LogisticAliJiSuApiService::class);
@@ -282,6 +259,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('LogisticYTOService', LogisticYTOService::class);
         app()->singleton('LogisticZopService', LogisticZopService::class);
         app()->singleton('LogisticZopService', LogisticZopService::class);
+        app()->singleton('LogisticZopService', LogisticZopService::class);
         app()->singleton('MaterialBoxModelService',MaterialBoxModelService::class);
         app()->singleton('MaterialBoxService', MaterialBoxService::class);
         app()->singleton('MenuService',MenuService::class);
@@ -303,6 +281,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OrderPackageCommoditiesService', OrderPackageCommoditiesService::class);
         app()->singleton('OrderPackageCommoditySerialNumberService', OrderPackageCommoditySerialNumberService::class);
         app()->singleton('OrderPackageExceptionTypeCountingRecordService', OrderPackageExceptionTypeCountingRecordService::class);
+        app()->singleton('OrderPackageExpressBillPrintRecordService',OrderPackageExpressBillPrintRecordService::class);
         app()->singleton('OrderPackageReceivedSyncRecordService', OrderPackageReceivedSyncRecordService::class);
         app()->singleton('OrderPackageReceivedSyncService', OrderPackageReceivedSyncService::class);
         app()->singleton('OrderPackageRemarkService',OrderPackageRemarkService::class);
@@ -336,9 +315,12 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OwnerSundryFeeDetailService',OwnerSundryFeeDetailService::class);
         app()->singleton('OwnerWayBillFeeDetailService',OwnerWayBillFeeDetailService::class);
         app()->singleton('OwnerWaybillSettlementBillService',OwnerWaybillSettlementBillService::class);
+        app()->singleton('PDDDeliveryService',PDDDeliveryService::class);
         app()->singleton('PackageService', PackageService::class);
         app()->singleton('PackageStatisticsService', PackageStatisticsService::class);
+        app()->singleton('PrintPartImageService',PrintPartImageService::class);
         app()->singleton('PrintPartService',PrintPartService::class);
+        app()->singleton('PrintService',PrintService::class);
         app()->singleton('PrintTemplateService',PrintTemplateService::class);
         app()->singleton('ProcessMethodService', ProcessMethodService::class);
         app()->singleton('ProcessService', ProcessService::class);
@@ -356,6 +338,8 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('RequirementService',RequirementService::class);
         app()->singleton('RequirementUserService',RequirementUserService::class);
         app()->singleton('RoleService',RoleService::class);
+        app()->singleton('SFDeliveryService',SFDeliveryService::class);
+        app()->singleton('SFQHDDeliveryService',SFQHDDeliveryService::class);
         app()->singleton('SettlementBillsAreaFeeService',SettlementBillsAreaFeeService::class);
         app()->singleton('SettlementIndemnityFeeService',SettlementIndemnityFeeService::class);
         app()->singleton('ShopService', ShopService::class);
@@ -377,6 +361,10 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('StoreItemService', StoreItemService::class);
         app()->singleton('StoreService', StoreService::class);
         app()->singleton('SupplierService', SupplierService::class);
+        app()->singleton('TBDeliveryService',TBDeliveryService::class);
+        app()->singleton('TerminalPrinterLogisticService',TerminalPrinterLogisticService::class);
+        app()->singleton('TerminalPrinterService',TerminalPrinterService::class);
+        app()->singleton('TerminalService',TerminalService::class);
         app()->singleton('UnitService', UnitService::class);
         app()->singleton('UserOwnerGroupService', UserOwnerGroupService::class);
         app()->singleton('UserService', UserService::class);
@@ -396,4 +384,56 @@ class AppServiceProvider extends ServiceProvider
         Menu::observe(MenuObserver::class);
         Authority::observe(AuthorityObserver::class);
     }
+
+    private function registerProvider()
+    {
+        if(env('APP_ENV')!='production'){
+            $this->app->register(\Barryvdh\Debugbar\ServiceProvider::class);
+            $this->app->register(TinkerServiceProvider::class);
+        }
+    }
+
+    private function appendExtension()
+    {
+        Schema::defaultStringLength(191);
+        //扩展身份证验证规则
+        Validator::extend('identity_cards', function($attribute, $value, $parameters) {
+            return preg_match('/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)/', $value);
+        });
+        View::share('pageUuid',Uuid::uuid4());
+        \Illuminate\Database\Query\Builder::macro('sql', function () {
+            $bindings = $this->getBindings();
+            $sql = str_replace('?',"'%s'",$this->toSql());
+            return vsprintf($sql, $bindings);
+        });
+        Builder::macro('sql', function(){
+            return ($this->getQuery()->sql());
+        });
+    }
+
+    private function someTask()
+    {
+        Queue::failing(function (JobFailed $event) {
+            (new Controller())->log(__METHOD__, 'EventError_', json_encode($event));
+            $payload = $event->job->payload();
+            $displayName = $payload['displayName'];
+            //快递信息同步失败计数
+            /** @var  $logisticSyncRecordService  LogisticSyncRecordService*/
+            $logisticSyncRecordService = app("LogisticSyncRecordService");
+            if ($logisticSyncRecordService->isLogisticSyncJob($displayName)) {
+                $logisticSyncRecordService->logisticSyncRecord($displayName, 'failed_count');
+            }
+        });
+        //任务成功后的回调
+        Queue::after(function (JobProcessed $event) {
+            //快递信息同步成功计数
+            $payload = $event->job->payload();
+            $displayName = $payload['displayName'];
+            /** @var  $logisticSyncRecordService  LogisticSyncRecordService*/
+            $logisticSyncRecordService = app("LogisticSyncRecordService");
+            if ($logisticSyncRecordService->isLogisticSyncJob($displayName)) {
+                $logisticSyncRecordService->logisticSyncRecord($displayName, 'succeed_count');
+            }
+        });
+    }
 }

+ 12 - 13
app/Providers/EventServiceProvider.php

@@ -39,19 +39,18 @@ class EventServiceProvider extends ServiceProvider
         'App\Events\GitPushedEvent' => [
             'App\Listeners\GitPushedSendEmailListener'
         ],
-
-        'App\Events\AddOrUpdateOrderIssues' => [//问题件新增或更新
-            'App\Listeners\AddOrUpdateOrderIssuesListener',//将对应的order_packages的数据的异常装变更
-        ],
-        'App\Events\OrderIssueProcessLogCreateEvent' => [//orderIssue增添日志时
-            'App\Listeners\UpdateOrderPackageExceptionListener',//将对应的order_packages的数据的异常装变更为无
-        ],
-        'App\Events\UpdateOrderPackageExceptionListenerEvent' => [//order_packages的数据的异常数据变更时
-            'App\Listeners\UpdateOrderPackageExceptionTypeCountingRecordListener',//更新OrderPackageExceptionTypeCountingRecord的统计信息
-        ],
-        'App\Events\SettlementBillCreateEvent' => [
-            'App\Listeners\SettlementBillCreateListener'
-        ],
+//        'App\Events\AddOrUpdateOrderIssues' => [//问题件新增或更新
+//            'App\Listeners\AddOrUpdateOrderIssuesListener',//将对应的order_packages的数据的异常装变更
+//        ],
+//        'App\Events\OrderIssueProcessLogCreateEvent' => [//orderIssue增添日志时
+//            'App\Listeners\UpdateOrderPackageExceptionListener',//将对应的order_packages的数据的异常装变更为无
+//        ],
+//        'App\Events\UpdateOrderPackageExceptionListenerEvent' => [//order_packages的数据的异常数据变更时
+//            'App\Listeners\UpdateOrderPackageExceptionTypeCountingRecordListener',//更新OrderPackageExceptionTypeCountingRecord的统计信息
+//        ],
+//        'App\Events\SettlementBillCreateEvent' => [
+//            'App\Listeners\SettlementBillCreateListener'
+//        ],
     ];
 
     /**

+ 6 - 1
app/Providers/RouteServiceProvider.php

@@ -16,6 +16,11 @@ class RouteServiceProvider extends ServiceProvider
      */
     protected $namespace = 'App\Http\Controllers';
 
+    /**
+     * @var string
+     */
+    protected $apinamespace = 'App\Http\ApiControllers';
+
     /**
      * Define your route model bindings, pattern filters, etc.
      *
@@ -69,7 +74,7 @@ class RouteServiceProvider extends ServiceProvider
     {
         Route::prefix('api')
              ->middleware('api')
-             ->namespace($this->namespace)
+             ->namespace($this->apinamespace)
              ->group(base_path('routes/api.php'));
         Route::prefix('apiLocal')
              ->middleware('apiLocal')

+ 2 - 0
app/Requirement.php

@@ -42,6 +42,8 @@ class Requirement extends Model
             '待验收'=>3,
             '验收通过'=>4,
             '验收未通过'=>5,
+            '待审核'=>6,
+            '已驳回'=>7,
         ],
     ];
     function __construct(array $attributes = [])

+ 20 - 4
app/Services/CacheShelfService.php

@@ -2,8 +2,10 @@
 
 namespace App\Services;
 
+use App\Components\ErrorPush;
 use App\Events\BroadcastToStation;
 use App\Exceptions\ErrorException;
+use App\Jobs\CacheShelfTaskJob;
 use App\Station;
 use App\StationTaskMaterialBox;
 use App\Traits\ServiceAppAop;
@@ -14,7 +16,7 @@ use Illuminate\Database\Eloquent\Collection;
 
 class   CacheShelfService
 {
-    use ServiceAppAop;
+    use ServiceAppAop,ErrorPush;
 
     protected $modelClass = Station::class;
 
@@ -63,10 +65,9 @@ class   CacheShelfService
                 return ['success' => false,'errMsg' => '上架任务失败'];
             };
             if ($result===true){//任务存在且成功 绿灯
-                $this->lightUp($station->code);
+                $this->lightUp($station->code,'1','0',['title'=>"操作完成,等待入库"]);
                 return ['success' => true];
             }
-            app("StationService")->locationFreed($station->code);
         }
         try {
             $bool = $this->putBinToStore($station);                         // 推送任务
@@ -96,7 +97,8 @@ class   CacheShelfService
 
         /** @var StationTaskMaterialBox $stationTaskMaterialBox */
         $stationTaskMaterialBox = app("StorageService")->createWarehousingTask($this->stationService->getStation_byType('立库')["id"],$station->materialBox->id);
-
+        $this->lightUp($station->code,'3','0',['title'=>"等待机器人拿走,请勿操作"]);
+        Cache::forever("CACHE_SHELF_OCCUPANCY_{$station->id}",true);
         return $this->foreignHaiRoboticsService->putBinToStore_fromCacheShelf($stationTaskMaterialBox, $station);
     }
 
@@ -202,4 +204,18 @@ class   CacheShelfService
 
         return ['success' => true];
     }
+
+    /**
+     * 料箱被取走
+     *
+     * @param Station|\stdClass $station
+     */
+    public function boxHasBeenTaken($station)
+    {
+        app("StationService")->locationFreed($station->code); //释放库位,解除绑定料箱
+        $available=Cache::get("CACHE_SHELF_AVAILABLE",0)+1;//获取可用缓存架数量 plus当前
+        Cache::forever("CACHE_SHELF_AVAILABLE",$available);
+        $this->_stationCacheLightOff($station->code);
+        CacheShelfTaskJob::dispatch("CACHE_SHELF_AVAILABLE",$available)->delay(now()->addSeconds(config("haiRou.cacheShelf.outBinAwait",3)));
+    }
 }

+ 112 - 0
app/Services/DeliveryService.php

@@ -0,0 +1,112 @@
+<?php
+
+namespace App\Services;
+
+use App\OracleDocOrderDeliveryInfo;
+use App\OracleDOCOrderHeader;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Cache;
+
+class DeliveryService
+{
+
+    public function getDelivery($printStr): array
+    {
+        list($batchCodes, $orderCodes, $logisticNumbers) = $this->conversionPrintData($printStr);
+
+        if ($batchCodes) {
+            $orderHeaders = OracleDOCOrderHeader::query()->selectRaw('orderno')->whereIn('WaveNo', $batchCodes)->get()->toArray();
+            $orderCodes = array_unique(array_merge($orderCodes, array_column($orderHeaders, 'orderno')));
+        }
+
+        if ($orderCodes) {
+            $deliveryInfo = OracleDocOrderDeliveryInfo::query()->selectRaw('trackingNo')->whereIn('orderno', $orderCodes)->get()->toArray();
+            $deliveryNos = OracleDOCOrderHeader::query()->selectRaw('deliveryno')->whereIn('orderno', $orderCodes)->get()->toArray();
+            $logisticNumbers = array_unique(array_merge($logisticNumbers, array_column($deliveryInfo, 'trackingno'), array_column($deliveryNos, 'deliveryno')));
+        }
+
+        $OracleDocOrderDeliveryInfos = OracleDocOrderDeliveryInfo::query()->with('docOrderHeader.docOrderDeliveryInfo')->whereIn('trackingNo', $logisticNumbers)->get();
+
+        $tbParams = app(TBDeliveryService::class)->getDeliveryInfo($OracleDocOrderDeliveryInfos);
+
+        $pddParams = app(PDDDeliveryService::class)->getDeliveryInfo($OracleDocOrderDeliveryInfos);
+
+        $sfParams = app(SFDeliveryService::class)->getDeliveryInfo($OracleDocOrderDeliveryInfos);
+
+        $jdParams = app(JDDeliveryService::class)->getDeliveryInfo($logisticNumbers);
+
+        $sfQhdParams = app(SFQHDDeliveryService::class)->getDeliveryInfo($logisticNumbers);
+
+        return array_merge($tbParams, $pddParams, $sfParams, $jdParams, $sfQhdParams);
+    }
+
+    public function conversionPrintData($printStr): array
+    {
+        preg_match_all('/[\w]+/', $printStr, $nos);
+
+        foreach ($nos[0] as $no) {
+            if (strstr($no, 'SO') || strstr($no, 'so')) $orderCodes[] = $no;
+            elseif (strstr($no, 'W') || strstr($no, 'w')) $batchesCodes[] = $no;
+            else $logisticNumbers[] = $no;
+        }
+        return [$batchesCodes ?? [], $orderCodes ?? [], $logisticNumbers ?? []];
+    }
+
+
+    /**
+     * 快递面单填充自定义区域内容 或 自制面单
+     * @param array $items
+     * @return array
+     */
+    public function customProcessing(array $items): array
+    {
+        foreach ($items as $key => &$item) {
+            if ($item['is_process'] == true) continue;
+            switch ($item['component_type']) {
+                case 'TB':
+                    $items[$key] = app(TBDeliveryService::class)->processing($item);
+                    break;
+                case 'PDD':
+                    $items[$key] = app(PDDDeliveryService::class)->processing($item);
+                    break;
+                default:
+                    break;
+            }
+        }
+        return $items;
+    }
+
+    /**
+     * 根据缓存删除十分钟前的文件
+     */
+    public function destroyFileOfCache()
+    {
+        if (Cache::has('print-template-file-list')) {
+            $arr = Cache::get('print-template-file-list');
+            $now = Carbon::now();
+            foreach ($arr as $key => $item) {
+                $time = (new Carbon($item['time']))->addMilliseconds(10);
+                if ($now->lt($time)) {
+                    if (file_exists($item['path'])) {
+                        unlink($item['path']);
+                    }
+                    unset($arr[$key]);
+                }
+            }
+            Cache::put('print-template-file-list', $arr);
+        }
+    }
+
+    public function pushClearCache($path)
+    {
+        if (!Cache::has("print-template-file-list")){
+            Cache::put('print-template-file-list',[$path]);
+            return;
+        }
+        $arr = Cache::get("print-template-file-list");
+        $arr[] = $path;
+        Cache::put('print-template-file-list',$arr);
+    }
+
+
+}

+ 165 - 0
app/Services/Express/CaiNiaoExpress.php

@@ -0,0 +1,165 @@
+<?php
+
+
+namespace App\Services\Express;
+
+
+use Illuminate\Support\Facades\Http;
+
+class CaiNiaoExpress implements expressinterface
+{
+
+    private $app_key = '';
+    private $sign_method = '';
+    private $target_app_key = '';
+
+    private $searchurl = '';
+    private $getelectronicsingleurl = '';
+    private $cancelelectronicsingleurl = '';
+    private $updateelectronicsingleurl = '';
+
+    /**
+     * @inheritdoc
+     */
+    function searchbalance()
+    {
+        $response = http::get($this->searchurl,[
+            'cp_code' => "",         //  物流服务商编码 require
+            'shipping_address' => [
+                'area' => '',        // 区地址
+                'province' => '',    // 省地址 require
+                'town' => '',        // 街道\镇名(四级地址)
+                'address_detail' => '',// 详细地址 require
+                'city' => '', // 市级
+            ],
+            // 订单数据
+            'trade_order_info_cols' => [
+                'consignee_name' => '', // 收货人 require
+                'order_channels_type' => '', // 订单渠道 require
+                'trade_order_list' => [], // 交易订单列表 require
+                // 收\发货地址
+                'consignee_address' => [
+                    'area' => '',        // 区地址
+                    'province' => '',    // 省地址 require
+                    'town' => '',        // 街道\镇名(四级地址)
+                    'address_detail' => '',// 详细地址 require
+                    'city' => '', // 市级
+                ],
+                'send_phone' => '', // 发货人联系方式
+                'weight' => '',     // 包裹重量
+                'send_name' => '',   // 发货人姓名
+                // 包裹里面的商品名称 require
+                'package_items' => [
+                    [
+                        'item_name' => '', // 商品名称  require
+                        'count' => '',     // 商品数量  require
+                    ]
+                ],
+                'logistics_service_list' => [
+                    [
+                        'service_value4_json' => '', // 服务类型值,json格式标识
+                        'service_code' => ''    // 服务编码
+                    ]
+                ],
+                'product_type' => '',  // 快递服务产品类型编码
+                'real_user_id' => '',    // 使用者id
+                'volume' => '',    // 包裹体积(立方厘米)
+                'package_id' => '', // 包裹号(或者erp订单号)
+            ]
+        ]);
+
+    }
+
+    /**
+     * @inheritdoc
+     */
+    function getelectronicsingle()
+    {
+    }
+
+    /**
+     * @inheritdoc
+     */
+    function cancelelectronicsingle()
+    {
+    }
+
+    function searElectronicSingle()
+    {
+        // TODO: Implement searElectronicSingle() method.
+    }
+
+    /**
+     * @inheritdoc
+     */
+    function saveelectronicsingle()
+    {
+    }
+
+    /**
+     * @inheritdoc
+     */
+    function updateelectronicsingle()
+    {
+    }
+
+
+    private $response = [
+        [
+            'short_address' => '', // 根据收货地址返回大头笔信息
+            // 面单对应的订单列
+            'trade_order_info' => [
+                'item_name' => '', // 商品名称
+                'consignee_name' => '', // 收货人
+                'ali_order' => '', //是否阿里系订单
+                'short_address' => '' , // 大头笔
+                'order_channels_type' => '', // 订单渠道
+                // 交易订单列表
+                'trade_order_list' => [],
+                'waybill_code' => '', // 面单号
+                'consignee_phone' => '', // 收货人联系方式
+                // 收货人地址
+                'consignee_address' => [
+                    'area' => '',        // 区地址
+                    'province' => '',    // 省地址 require
+                    'town' => '',        // 街道\镇名(四级地址)
+                    'address_detail' => '',// 详细地址 require
+                    'city' => '',       // 市级
+                ],
+                'send_phone' => '',    // 发货人联系方式
+                'weight' => '',        // 包裹重量(克)
+                'send_name' => '',     // 发货人姓名
+                'order_type' => '' ,   // 订单渠道来源
+                'package_items' => [
+                    [
+                        'item_name' => '',    // 商品名称
+                        'count' => '' ,       // 商品数量
+                    ]
+                ],
+                'logistics_service_list' => [
+                    [
+                        [
+                            'service_value4_json' => '', // 服务类型值,json格式表示
+                            'service_code' => '',       // 服务编码
+                        ]
+                    ]
+                ],
+                'product_type' => '',    // 快递服务产品类型编码
+                'real_user_id' => '',    // 使用者id
+                'volume' => '',          // 包裹体积(立方厘米)
+                'package_id' => '',      // 包裹号(或者erp订单号)
+            ],
+            'waybill_code' => '',        // 返回的面单号
+            'package_center_code' => '', // 集包地代码
+            'package_center_name' => '', // 集包地名称
+            'print_config' => '',        // 打印配置项,传给ali-print组件
+            'shipping_branch_code' => '',// 面单号对应的物流服务商网点(分支机构)代码
+            'consignee_branch_name' => '',// 包裹对应的派件(收件)物流服务商网点(分支机构)名称
+            'shipping_branch_name' => '', // 面单号对于的物流服务商网点(分支机构)名称
+            'consignee_branch_code' => '',// 包裹对应的派件(收件)物流服务商网点(分支机构)代码
+
+        ]
+    ];
+
+
+}

+ 52 - 0
app/Services/Express/ExpressInterface.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Services\Express;
+
+interface ExpressInterface
+{
+
+    /**
+     * 查询余额
+     *
+     * @return mixed
+     */
+    function searchBalance();
+
+    /**
+     * 获取快递面单
+     *
+     * @return mixed
+     */
+    function getElectronicSingle();
+
+    /**
+     * 取消快递面单
+     *
+      * @return mixed
+     */
+    function cancelElectronicSingle();
+
+
+    /**
+     * 查询面单
+     *
+     * @return mixed
+     */
+    function searElectronicSingle();
+
+    /**
+     * 对获取的快递面单进行保存
+     *
+     * @return mixed
+     */
+    function saveElectronicSingle();
+
+
+    /**
+     * 更新快递信息
+     * @return mixed
+     */
+    function updateElectronicSingle();
+
+
+}

+ 68 - 0
app/Services/Express/PDDExpress.php

@@ -0,0 +1,68 @@
+<?php
+
+
+namespace App\Services\Express;
+
+
+class PDDExpress implements ExpressInterface
+{
+    // TODO 目前获取快递单号请求参数
+
+    private $app_key = '';
+    private $sign_method = '';
+    private $target_app_key = '';
+
+    private $searchUrl = '';
+    private $getElectronicSingleUrl = '';
+    private $cancelElectronicSingleUrl = '';
+    private $updateElectronicSingleUrl = '';
+
+    /**
+     * @inheritDoc
+     */
+    function searchBalance()
+    {
+    }
+
+    /**
+     * @inheritDoc
+     */
+    function getElectronicSingle()
+    {
+        // TODO: Implement getElectronicSingle() method.
+    }
+
+    /**
+     * @inheritDoc
+     */
+    function cancelElectronicSingle()
+    {
+        // TODO: Implement cancelElectronicSingle() method.
+    }
+
+    function searElectronicSingle()
+    {
+        // TODO: Implement searElectronicSingle() method.
+    }
+
+    /**
+     * @inheritDoc
+     */
+    function saveElectronicSingle()
+    {
+        // TODO: Implement saveElectronicSingle() method.
+    }
+
+    /**
+     * @inheritDoc
+     */
+    function updateElectronicSingle()
+    {
+        // TODO: Implement updateElectronicSingle() method.
+    }
+
+    private $response = [
+
+    ];
+
+}

+ 16 - 7
app/Services/ForeignHaiRoboticsService.php

@@ -8,6 +8,7 @@ use App\Components\ErrorPush;
 use App\Exceptions\ErrorException;
 use App\Exceptions\Exception;
 use App\Jobs\CacheShelfTaskJob;
+use App\Log;
 use App\MaterialBox;
 use App\Station;
 use App\StationTask;
@@ -141,10 +142,13 @@ class ForeignHaiRoboticsService
      * @param Collection $taskMaterialBoxes
      * @param string $groupIdPrefix
      * @param string $mode
+     * @param int $priority
+     * @param bool $isSequenced
      * @return bool
      * @throws ErrorException|Exception
      */
-    public function fetchGroup_multiLocation(Collection $toLocations, Collection $taskMaterialBoxes, $groupIdPrefix='', $mode='立架出至输送线', int $priority = 10): bool
+    public function fetchGroup_multiLocation(Collection $toLocations, Collection $taskMaterialBoxes,string $groupIdPrefix='',string
+        $mode='立架出至输送线', int $priority = 10, bool $isSequenced = true): bool
     {
         $dataToPost=$this->makeJson_move_multi(
             $taskMaterialBoxes,
@@ -152,7 +156,8 @@ class ForeignHaiRoboticsService
             null,
             $toLocations,
             $groupIdPrefix,
-            $priority
+            $priority,
+            $isSequenced ? 1 : 0
         );
         return $this->controlHaiRobot($dataToPost,$taskMaterialBoxes,$mode);
     }
@@ -351,10 +356,6 @@ class ForeignHaiRoboticsService
         $binCode
     ):bool{
         $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
-        if ($status==1){ //海柔失败
-            $this->push(__METHOD__."->".__LINE__,"海柔任务异常",json_encode(request()->input()));
-            return false;
-        }
         //获取下达任务
         /** @var StationTaskMaterialBox|\stdClass $stationTaskMaterialBox */
         $stationTaskMaterialBox = $stationTaskMaterialBox_id ? StationTaskMaterialBox::query()->with("materialBox:id,code")
@@ -363,6 +364,11 @@ class ForeignHaiRoboticsService
             $this->push(__METHOD__."->".__LINE__,"海柔任务不存在",json_encode(request()->input()));
             return false;
         }
+        if ($status==1){ //海柔失败
+            $this->push(__METHOD__."->".__LINE__,"海柔任务异常",json_encode(request()->input()));
+            $stationTaskMaterialBox->update(['status'=>"异常"]);
+            return false;
+        }
         if ($stationTaskMaterialBox->materialBox->code != $binCode){
             $this->push(__METHOD__."->".__LINE__,"海柔任务料箱号不匹配",json_encode(request()->input()));
             return false;
@@ -407,7 +413,6 @@ class ForeignHaiRoboticsService
             $response = Http::post(config('api.haiq.storage.moveBin'), $dataToPost);
             if(isset($response->json()['code'])&&$response->json()['code']==500)
                 throw new ErrorException('机器人500错误:'.json_encode($response->json()));
-            LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.52:');
             LogService::log(__METHOD__,'runMany','波次任务分配6.r5f2c1.53:'.json_encode($response->json()));
         }catch (\Exception $e){
             LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.54:'.json_encode($dataToPost).$e->getMessage());
@@ -496,6 +501,10 @@ class ForeignHaiRoboticsService
         }
         if ($stationCollection->count()>0){
             if (!$this->fetchGroup_multiLocation($stationCollection,$collection,'','立架出至缓存架')) return null;
+            app("StationService")->locationOccupyMulti($stationCollection->toArray());
+            $stationCollection->each(function ($code){
+                app("CacheShelfService")->lightUp($code,'3','0',["title"=>"机器人取箱中,禁止操作"]);
+            });
         }
         return $stations->count()==$stationCollection->count();
     }

+ 302 - 185
app/Services/HandInStorageService.php

@@ -3,6 +3,7 @@
 namespace App\Services;
 
 use App\CommodityBarcode;
+use App\OracleActTransactionLog;
 use App\OracleBasCode;
 use App\OracleBasCustomer;
 use App\OracleBasForwardingLoc;
@@ -16,6 +17,7 @@ use App\OracleInvLotLocId;
 use App\Traits\ServiceAppAop;
 use App\ValueStore;
 use Carbon\Carbon;
+use Decimal\Decimal;
 use Doctrine\DBAL\Schema\AbstractAsset;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
@@ -35,20 +37,31 @@ class HandInStorageService
      * @return object
      * 根据asn单号获取 总预期数量 总已收数量
      */
-    public function getAsnQty($asnno)
+    public function getAsnQty($asnno): object
     {
-        $asnQty=OracleDOCASNDetail::query()
-            ->select('expectedqty','receivedqty')
-            ->where('asnno',$asnno)
+        $asnQty = OracleDOCASNDetail::query()
+            ->select('expectedqty', 'receivedqty','receivedqty_each','expectedqty_each')
+            ->where('asnno', $asnno)
             ->get();
         $expectedqty=0;
         $receivedqty=0;
         foreach ($asnQty as $qty){
-            $expectedqty+=$qty->expectedqty;
-            $receivedqty+=$qty->receivedqty;
+            if ($qty->expectedqty) {
+                $expectedqty+=$qty->expectedqty;
+            }else{
+                $expectedqty+=$qty->expectedqty_each??0;
+            }
+
+            if ($qty->receivedqty){
+                $receivedqty+=$qty->receivedqty;
+            }else{
+                $receivedqty+=$qty->receivedqty_each??0;
+            }
+
         }
-        return (object)array('expectedqty'=>$expectedqty,'receivedqty'=>$receivedqty);
+        return (object)array('expectedqty' => $expectedqty, 'receivedqty' => $receivedqty);
     }
+
     /**
      * @param array $info
      * @return bool|int
@@ -56,19 +69,20 @@ class HandInStorageService
      */
     public function checkForwardingLoc(array $info)
     {
-        $res=OracleBasCustomer::query()
-            ->where('customerid',$info['customerid'])
-            ->where('customer_type','OW')
-            ->where('udf1','Y')->count(); //查询此货主是否必须有拣货位
-        if ($res>0) {
-            $amount=OracleBasForwardingLoc::query()
-                ->where('customerid',$info['customerid'])
-                ->where('sku',$info['sku'])
+        $res = OracleBasCustomer::query()
+            ->where('customerid', $info['customerid'])
+            ->where('customer_type', 'OW')
+            ->where('udf1', 'Y')->count(); //查询此货主是否必须有拣货位
+        if ($res > 0) {
+            $amount = OracleBasForwardingLoc::query()
+                ->where('customerid', $info['customerid'])
+                ->where('sku', $info['sku'])
                 ->count();
-            if ($amount==0)return 1;//请维护拣货位!
+            if ($amount == 0) return 1;//请维护拣货位!
         }
         return true;
     }
+
     /**
      * @param array $info
      * @return bool|int
@@ -76,9 +90,9 @@ class HandInStorageService
      */
     public function checkWidthHeight(array $info)
     {
-        $basSku=OracleBasSKU::query()->where('customerid',$info['customerid'])->where('sku',$info['sku'])->first();
-        if (!$basSku)return 1;//需要维护产品档案
-        if ($basSku->skulength<=0||$basSku->skuwidth<=0||$basSku->skuhigh<=0)return 2;//需要维护该产品档案中的长宽高
+        $basSku = OracleBasSKU::query()->where('customerid', $info['customerid'])->where('sku', $info['sku'])->first();
+        if (!$basSku) return 1;//需要维护产品档案
+        if ($basSku->skulength <= 0 || $basSku->skuwidth <= 0 || $basSku->skuhigh <= 0) return 2;//需要维护该产品档案中的长宽高
         return true;
     }
 
@@ -89,11 +103,12 @@ class HandInStorageService
      */
     public function checkCubicWeight(array $info)
     {
-        $basSku=OracleBasSKU::query()->where('customerid',$info['customerid'])->where('sku',$info['sku'])->first();
-        if (!$basSku)return 1;//需要维护产品档案
-        if ($basSku->grossweight<=0||$basSku->cube<=0)return 2;//需要维护该产品档案中的重量体积
+        $basSku = OracleBasSKU::query()->where('customerid', $info['customerid'])->where('sku', $info['sku'])->first();
+        if (!$basSku) return 1;//需要维护产品档案
+        if ($basSku->grossweight <= 0 || $basSku->cube <= 0) return 2;//需要维护该产品档案中的重量体积
         return true;
     }
+
     /**
      * @param array $info
      * @param array $param
@@ -110,38 +125,52 @@ class HandInStorageService
         if (!$location) return 1;//库位不存在
 
         if ($location['mix_flag'] == 'N' && $location['mix_lotflag'] == 'N') { // 库位:产品和批次都不可混放
-            $inv = OracleInvLotLocId::query()->where('locationid', $info['location'])->first();
+            $inv = OracleInvLotLocId::query()->with('oracleInvLotAtt:lotnum,lotatt01,lotatt02,lotatt03,lotatt04,lotatt05,lotatt08')
+                ->where('locationid', $info['location'])->first();
 
             if (!$inv) return true; //当前库位无库存余量 可直接入库
 
             if ($inv['customerid'] == $param['customerid'] && $inv['sku'] == $param['sku']
-                && $inv['lotnum'] == $param['plantolotnum'])
+                && $inv['oracleInvLotAtt']['lotatt01'] == $param['lotatt01']
+                && $inv['oracleInvLotAtt']['lotatt02'] == $param['lotatt02']
+                && $inv['oracleInvLotAtt']['lotatt04'] == $param['lotatt04']
+                && $inv['oracleInvLotAtt']['lotatt05'] == $param['lotatt05']
+                && $inv['oracleInvLotAtt']['lotatt08'] == $param['lotatt08']
+            )
                 return true;
             else return 2; //库位:产品和批次不可混放
         }
 
 
         if ($location['mix_flag'] == 'Y' && $location['mix_lotflag'] == 'N') {//库位:产品可混放,批次不可
-            $invs = OracleInvLotLocId::query()->where('locationid', $info['location'])->get();
+            $invs = OracleInvLotLocId::query()->with('oracleInvLotAtt:lotnum,lotatt01,lotatt02,lotatt03,lotatt04,lotatt05,lotatt08')
+                ->where('locationid', $info['location'])->get();
 
             if ($invs->count() == 0) return true; //当前库位无库存余量 可直接入库
 
             $skuInvs = [];    // 库位没有该商品
             foreach ($invs as $inv) {
-                if ($inv['customerid'] != $param['customerid'] || $inv['sku'] != $param['sku']) {  // 库位没有该商品
+                if ($inv['customerid'] != $param['customerid'] && $inv['sku'] != $param['sku']) {  // 库位没有该商品
                     $skuInvs[] = $inv;
                     continue;
                 }
-                if ($inv['lotnum'] == $param['plantolotnum']) return true; // 批次相同
+                if ($inv['oracleInvLotAtt']['lotatt01'] == $param['lotatt01']
+                && $inv['oracleInvLotAtt']['lotatt02'] == $param['lotatt02']
+                && $inv['oracleInvLotAtt']['lotatt04'] == $param['lotatt04']
+                && $inv['oracleInvLotAtt']['lotatt05'] == $param['lotatt05']
+                && $inv['oracleInvLotAtt']['lotatt08'] == $param['lotatt08']) return true; // 批次相同
                 return 3;   //库位:产品相同,不能混放批次
             }
             if (count($skuInvs) == count($invs)) return true;
         }
         if ($location['mix_flag'] == 'N' && $location['mix_lotflag'] == 'Y') {  //库位:产品不可混放,批次可混放
-            $inv = OracleInvLotLocId::query()->where('locationid', $info['location'])->first();
+            $inv = OracleInvLotLocId::query()
+                ->where('locationid', $info['location'])
+                ->where('qty','>',0) //占用库位忽略当条库存余量
+                ->first();
             if (!$inv) return true; //当前库位无库存余量 可直接入库
 
-            if ($inv['customerid'] == $param['customerid'] || $inv['sku'] == $param['sku']) return true;
+            if ($inv['customerid'] == $param['customerid'] && $inv['sku'] == $param['sku']) return true;
             else return 4; //库位:产品不能混放
         }
         // 库位
@@ -186,7 +215,7 @@ class HandInStorageService
     public function selectAsn($asn)
     {
         if (!$asn) return OracleDOCASNHeader::query()  //空扫
-            ->select(['asnno', 'asnreference1', 'asnstatus', 'addtime', 'customerid', 'asntype','notes'])
+        ->select(['asnno', 'asnreference1', 'asnstatus', 'addtime', 'customerid', 'asntype', 'notes'])
             ->where('asnstatus', '00')
             ->orderByDesc('addtime')
             ->limit(50)
@@ -194,13 +223,13 @@ class HandInStorageService
 
         if (strpos(strtoupper($asn), 'ASN') !== false) {  //asn 单号
             return OracleDOCASNHeader::query()
-                ->select(['asnno', 'asnreference1', 'asnstatus', 'addtime', 'customerid', 'asntype','notes'])
+                ->select(['asnno', 'asnreference1', 'asnstatus', 'addtime', 'customerid', 'asntype', 'notes'])
                 ->where('asnno', $asn)
                 ->whereIn('asnstatus', ['00', '30'])
                 ->get();
         } else {
             $asns = OracleDOCASNHeader::query()  //货主
-                ->select(['asnno', 'asnreference1', 'asnstatus', 'addtime', 'customerid', 'asntype','notes'])
+            ->select(['asnno', 'asnreference1', 'asnstatus', 'addtime', 'customerid', 'asntype', 'notes'])
                 ->where('customerid', strtoupper($asn))
                 ->whereIn('asnstatus', ['00', '30'])
                 ->get();
@@ -231,7 +260,7 @@ SQL;
     {
         $sql = <<<sql
  SELECT DOC_ASN_DETAILS.sku,DOC_ASN_DETAILS.expectedqty,DOC_ASN_DETAILS.skudescrc,DOC_ASN_DETAILS.asnlineno,DOC_ASN_DETAILS.asnno,
-       DOC_ASN_DETAILS.receivedqty,BAS_SKU.alternate_sku1
+       DOC_ASN_DETAILS.receivedqty,DOC_ASN_DETAILS.receivedqty_each,BAS_SKU.alternate_sku1
 FROM DOC_ASN_DETAILS LEFT JOIN BAS_SKU ON DOC_ASN_DETAILS.CUSTOMERID = BAS_SKU.CUSTOMERID AND DOC_ASN_DETAILS.SKU = BAS_SKU.SKU
 WHERE asnno = ? AND linestatus IN ('00','30')
 sql;
@@ -252,15 +281,15 @@ sql;
 SELECT DOC_ASN_DETAILS.sku,DOC_ASN_DETAILS.expectedqty,DOC_ASN_DETAILS.skudescrc,
        DOC_ASN_DETAILS.lotatt01, DOC_ASN_DETAILS.lotatt02, DOC_ASN_DETAILS.lotatt03, DOC_ASN_DETAILS.lotatt04,
        DOC_ASN_DETAILS.lotatt05, DOC_ASN_DETAILS.lotatt06, DOC_ASN_DETAILS.lotatt07, DOC_ASN_DETAILS.lotatt08,
-       DOC_ASN_DETAILS.asnlineno,DOC_ASN_DETAILS.asnno,DOC_ASN_DETAILS.receivedqty FROM DOC_ASN_DETAILS
+       DOC_ASN_DETAILS.asnlineno,DOC_ASN_DETAILS.asnno,DOC_ASN_DETAILS.receivedqty,DOC_ASN_DETAILS.receivedqty_each FROM DOC_ASN_DETAILS
          LEFT JOIN BAS_SKU ON DOC_ASN_DETAILS.CUSTOMERID = BAS_SKU.CUSTOMERID AND DOC_ASN_DETAILS.SKU = BAS_SKU.SKU
 WHERE ASNNO = ? AND LINESTATUS IN ('00','30') AND (ALTERNATE_SKU1 = ? OR ALTERNATE_SKU2 = ?  OR ALTERNATE_SKU3 = ?)
 sql;
         $asn_detail = DB::connection("oracle")->selectOne(DB::raw($sql), [$asnno, $skuOrBarcode, $skuOrBarcode, $skuOrBarcode]);
         if ($asn_detail) return $asn_detail;
         else return OracleDOCASNDetail::query()
-            ->select(['sku', 'expectedqty', 'skudescrc', 'asnlineno', 'asnno', 'receivedqty',
-                'lotatt01','lotatt02','lotatt03','lotatt04','lotatt05','lotatt06','lotatt07','lotatt08'])
+            ->select(['sku', 'expectedqty', 'skudescrc', 'asnlineno', 'asnno', 'receivedqty','receivedqty_each',
+                'lotatt01', 'lotatt02', 'lotatt03', 'lotatt04', 'lotatt05', 'lotatt06', 'lotatt07', 'lotatt08'])
             ->where('asnno', $asnno)
             ->where('sku', $skuOrBarcode)
             ->whereIn('linestatus', ['00', '30'])
@@ -317,18 +346,19 @@ sql;
      */
     public function getInvotlocid($barcode): array
     {
-        $sql=<<<sql
+        $sql = <<<sql
 select INV_LOT_LOC_ID.CUSTOMERID,BAS_SKU.ALTERNATE_SKU1,INV_LOT_LOC_ID.LOCATIONID,INV_LOT_ATT.LOTATT05,INV_LOT_ATT.LOTATT08,
+       INV_LOT_ATT.LOTATT01,INV_LOT_ATT.LOTATT02,INV_LOT_ATT.LOTATT03,INV_LOT_ATT.LOTATT04,
        sum(INV_LOT_LOC_ID.QTY) AS QTY from INV_LOT_LOC_ID
     left join BAS_SKU on INV_LOT_LOC_ID.CUSTOMERID=BAS_SKU.CUSTOMERID and INV_LOT_LOC_ID.SKU =BAS_SKU.SKU
     left join INV_LOT_ATT on INV_LOT_ATT.LOTNUM=INV_LOT_LOC_ID.LOTNUM
     where BAS_SKU.SKU in (select SKU from BAS_SKU where ALTERNATE_SKU1=? union
                       select SKU from BAS_SKU where ALTERNATE_SKU2=? union
                       select SKU from BAS_SKU where ALTERNATE_SKU3=? )
-group by INV_LOT_LOC_ID.CUSTOMERID,BAS_SKU.ALTERNATE_SKU1,INV_LOT_LOC_ID.LOCATIONID,INV_LOT_ATT.LOTATT05,INV_LOT_ATT.LOTATT08
+group by INV_LOT_LOC_ID.CUSTOMERID,BAS_SKU.ALTERNATE_SKU1,INV_LOT_LOC_ID.LOCATIONID,INV_LOT_ATT.LOTATT05,INV_LOT_ATT.LOTATT08,INV_LOT_ATT.LOTATT01,INV_LOT_ATT.LOTATT02,INV_LOT_ATT.LOTATT03,INV_LOT_ATT.LOTATT04
 sql;
         $invLots = DB::connection("oracle")->select(DB::raw($sql), [$barcode, $barcode, $barcode]);
-        if (!$invLots)return [];
+        if (!$invLots) return [];
         else return $invLots;
     }
 
@@ -337,10 +367,10 @@ sql;
      * @return array|int
      * 根据商品条码  获取完全收货状态  部分收货状态的 PA任务
      */
-    public function getTsk($trackNumber,$barCode): array
+    public function getTsk($trackNumber, $barCode): array
     {
         $sql = <<<sql
-select t.*, DOC_ASN_DETAILS.RECEIVEDQTY
+select t.*, DOC_ASN_DETAILS.RECEIVEDQTY,DOC_ASN_DETAILS.ReceivedQty_Each
 from (select TSK_TASKLISTS.CustomerID,
              TSK_TASKLISTS.DOCNO,
              TSK_TASKLISTS.Sku,
@@ -348,6 +378,12 @@ from (select TSK_TASKLISTS.CustomerID,
              TSK_TASKLISTS.PlanToID,
              DOC_ASN_DETAILS.SKUDESCRC,
              TSK_TASKLISTS.DOCLINENO,
+             TSK_TASKLISTS.LOTATT01,
+             TSK_TASKLISTS.LOTATT02,
+             TSK_TASKLISTS.LOTATT03,
+             TSK_TASKLISTS.LOTATT04,
+             TSK_TASKLISTS.LOTATT05,
+             TSK_TASKLISTS.LOTATT08,
              sum(TSK_TASKLISTS.PlanToQty) as qty
       from TSK_TASKLISTS
                LEFT JOIN DOC_ASN_DETAILS ON DOC_ASN_DETAILS.ASNNO = TSK_TASKLISTS.DOCNO AND
@@ -355,43 +391,45 @@ from (select TSK_TASKLISTS.CustomerID,
       where TSK_TASKLISTS.TASKTYPE = 'PA'
         AND TSK_TASKLISTS.TASKPROCESS = '00'
 sql;
-        if (!$trackNumber){ //没有输入条件  空扫
+        if (!$trackNumber) { //没有输入条件  空扫
             $owner_codes = app('OwnerService')->getIntersectPermitting(['code']);
-            if (count($owner_codes)>0){
-                $sql.=' AND TSK_TASKLISTS.CustomerID IN (';
-                foreach ($owner_codes as $index => $no){
-                    if ($index==0){
-                        $sql.="'".$no->code."'";
+            if (count($owner_codes) > 0) {
+                $sql .= ' AND TSK_TASKLISTS.CustomerID IN (';
+                foreach ($owner_codes as $index => $no) {
+                    if ($index == 0) {
+                        $sql .= "'" . $no->code . "'";
                         continue;
                     }
-                    $sql.=",'".$no->code."'";
+                    $sql .= ",'" . $no->code . "'";
                 }
-                $sql.=')';
-            }else{
+                $sql .= ')';
+            } else {
                 $sql .= ' AND TSK_TASKLISTS.CustomerID IS NULL ';
             }
 
-        }else{
-            if (strpos(strtoupper($trackNumber), 'ASN') !== false){
-                $sql.='AND TSK_TASKLISTS.DOCNO= ?'; //输入条件为asn单号
-            } else{ //不为asn号时 判断是否为货主
-                if ($this->checkUserOwnerAuth($trackNumber)){ //输入条件为货主
-                    $sql.=' AND TSK_TASKLISTS.CustomerID= ?';
-                }else{
-                    $sql.=' AND TSK_TASKLISTS.PlanToID= ?';  //不是货主 判断是否为跟踪号
+        } else {
+            if (strpos(strtoupper($trackNumber), 'ASN') !== false) {
+                $sql .= 'AND TSK_TASKLISTS.DOCNO= ?'; //输入条件为asn单号
+            } else { //不为asn号时 判断是否为货主
+                if ($this->checkUserOwnerAuth($trackNumber)) { //输入条件为货主
+                    $sql .= ' AND TSK_TASKLISTS.CustomerID= ?';
+                } else {
+                    $sql .= ' AND TSK_TASKLISTS.PlanToID= ?';  //不是货主 判断是否为跟踪号
                 }
             }
         }
 
-        if ($barCode)$sql.=" AND TSK_TASKLISTS.sku in (select SKU from BAS_SKU where ALTERNATE_SKU1='".$barCode."' union
-                                  select SKU from BAS_SKU where ALTERNATE_SKU2='".$barCode."' union
-                                  select SKU from BAS_SKU where ALTERNATE_SKU3='".$barCode."' )";
+        if ($barCode) $sql .= " AND TSK_TASKLISTS.sku in (
+                                    select SKU from BAS_SKU where ALTERNATE_SKU1='" . $barCode . "' union
+                                    select SKU from BAS_SKU where ALTERNATE_SKU2='" . $barCode . "' union
+                                    select SKU from BAS_SKU where ALTERNATE_SKU3='" . $barCode . "' union
+                                    select SKU from BAS_SKU where SKU='" . $barCode . "' )";
 
-        $sql.=' group by TSK_TASKLISTS.CustomerID, TSK_TASKLISTS.DOCNO, TSK_TASKLISTS.Sku, TSK_TASKLISTS.PlanToLotNum,
-               TSK_TASKLISTS.PlanToID, DOC_ASN_DETAILS.SKUDESCRC, TSK_TASKLISTS.DOCLINENO) t
+        $sql.=' group by TSK_TASKLISTS.CustomerID, TSK_TASKLISTS.DOCNO, TSK_TASKLISTS.Sku, TSK_TASKLISTS.PlanToLotNum, TSK_TASKLISTS.PlanToID, DOC_ASN_DETAILS.SKUDESCRC,
+         TSK_TASKLISTS.DOCLINENO, TSK_TASKLISTS.LOTATT01, TSK_TASKLISTS.LOTATT02, TSK_TASKLISTS.LOTATT03, TSK_TASKLISTS.LOTATT04, TSK_TASKLISTS.LOTATT05, TSK_TASKLISTS.LOTATT08) t
          left join DOC_ASN_DETAILS on t.DOCLINENO = DOC_ASN_DETAILS.ASNLINENO and t.DOCNO = DOC_ASN_DETAILS.ASNNO';
-        if ($trackNumber){
-            if ($this->checkUserOwnerAuth($trackNumber))$tasks = DB::connection("oracle")->select(DB::raw($sql), [strtoupper($trackNumber)]);
+        if ($trackNumber) {
+            if ($this->checkUserOwnerAuth($trackNumber)) $tasks = DB::connection("oracle")->select(DB::raw($sql), [strtoupper($trackNumber)]);
             else $tasks = DB::connection("oracle")->select(DB::raw($sql), [$trackNumber]);
         }else {$tasks = DB::connection("oracle")->select(DB::raw($sql));}
         if (!$tasks) return [];
@@ -406,8 +444,8 @@ sql;
     public function checkUserOwnerAuth($owner_code): bool
     {
         $owner_codes = app('OwnerService')->getIntersectPermitting(['code']);
-        $owner=$owner_codes->where('code','=',strtoupper($owner_code));
-        if ($owner->count()>0)return true;
+        $owner = $owner_codes->where('code', '=', strtoupper($owner_code));
+        if ($owner->count() > 0) return true;
         else return false;
     }
 
@@ -421,8 +459,8 @@ sql;
         if (!$tasks) return false; //获取任务失败
         return DB::connection("oracle")->transaction(function () use ($tasks, $info) { //单体嵌套事务 回滚FLUX失败任务
             foreach ($tasks as $task) {
-                $res=$this->checkExpiryPa($task,$info['location']);
-                if ($res!==true)return $res;
+                $res = $this->checkExpiryPa($task, $info['location']);
+                if ($res !== true) return $res;
                 if (!app("StorageService")->fluxPA($task, $info['location'])) {
                     DB::connection("oracle")->rollBack();
                     return false; //上架失败
@@ -431,23 +469,22 @@ sql;
             return true; //上架成功
         });
     }
-
     /**
      * @param $task
      * @param $location
      * @return bool|int
      * 上架校验效期
      */
-    public function checkExpiryPa($task,$location)
+    public function checkExpiryPa($task, $location)
     {
-        if (!$task->taskid)return 0;//任务id不存在
-        if (strpos($task->taskid,'MIX') !== false)return true;//合并拣货,不校验
+        if (!$task->taskid) return 0;//任务id不存在
+        if (strpos($task->taskid, 'MIX') !== false) return true;//合并拣货,不校验
 
         $sql = <<<sql
 select instr(DESCR,'拣货') as var_IsPickingArea from BAS_Zone where ZONE=(select PutawayZone from BAS_Location where LocationID = ?)
 sql;
         $basZone = DB::connection("oracle")->selectOne(DB::raw($sql), [$location]);
-        if ($basZone&&$basZone->var_ispickingarea>0) return true; //不是存储区,不校验
+        if ($basZone && $basZone->var_ispickingarea > 0) return true; //不是存储区,不校验
 
         $sql1 = <<<sql
 select SKU,LotAtt02,CustomerID from INV_LOT_ATT WHERE LOTNUM=?
@@ -464,8 +501,8 @@ sql;
       and attres.LotAtt02 > ?
       and zone.DESCR like '%拣货%'
 sql;
-        $invLotLocId=DB::connection("oracle")->selectOne(DB::raw($sql2), [$invLotAtt->sku,$invLotAtt->customerid,$task->fmlotnum,$invLotAtt->lotatt02]);
-        if ($invLotLocId&&$invLotLocId->var_amountofdecaying>0)return 1;//拣货区找到效期更新的同样货品,不能上架至存储区
+        $invLotLocId = DB::connection("oracle")->selectOne(DB::raw($sql2), [$invLotAtt->sku, $invLotAtt->customerid, $task->fmlotnum, $invLotAtt->lotatt02]);
+        if ($invLotLocId && $invLotLocId->var_amountofdecaying > 0) return 1;//拣货区找到效期更新的同样货品,不能上架至存储区
         return true;
     }
 
@@ -503,10 +540,11 @@ sql;
 
 
     /**
-     * @throws \Throwable
+     * @param array $info
+     * @return bool
      * fulx 手持收货
      */
-    public function fluxHandIn(array $info)
+    public function fluxHandIn(array $info): bool
     {
         $lotatt = array_filter($info, function ($key) {
             return strpos($key, 'lotatt') === 0;
@@ -522,31 +560,46 @@ sql;
         }
         $who = 'WAS' . (Auth::user() ? '-' . Auth::user()["name"] : '');
         $time = Carbon::now()->toDateTimeString();
-        return DB::connection("oracle")->transaction(function () use ($info, $invlotatt, $who, $time) {
+        $db = DB::connection("oracle");
+        $db->beginTransaction();
+        try {
+//        return DB::connection("oracle")->transaction(function () use ($info, $invlotatt, $who, $time) {
             //flux 批次号
             $lotNum = $this->getOrCreateLotNum($info, $invlotatt, $who, $time);
-            if (!$lotNum) {
-                DB::connection("oracle")->rollBack();
-                return false;
-            }
+            if (!$lotNum){$db->rollBack();return false;}
+
             //flux 创建入库事务
             $actTransactionLog = $this->setFluxActTransactionLog($info, $lotNum, $who, $time);
-            if (!$actTransactionLog) {
-                DB::connection("oracle")->rollBack();
-                return false;
-            }
+            if (count($actTransactionLog) == 0){$db->rollBack();return false;}
             //flux 创建上架任务
-            $this->setFluxTskTaskListPA($info, $invlotatt, $actTransactionLog, $who, $time);
+            $res=$this->setFluxTskTaskListPA($info, $invlotatt, $actTransactionLog, $who, $time);
+            if (!$res){$db->rollBack();return false;}
             //flux 完善库存余量
             $this->updateFluxInv($info, $lotNum, $who, $time, $actTransactionLog);
             //flux 更新asn_detail 和 asn_header 状态
-            return $this->updateFluxAsn($info, $invlotatt, $time, $who);
-        });
+            $result=$this->updateFluxAsn($info, $invlotatt, $time, $who);
+            if ($result){
+                $db->commit();
+                return true;
+            }else{
+                $db->rollBack();
+                return false;
+            }
+//        });
+        } catch (\Exception $e) {
+            $db->rollBack();
+            return false;
+        }
 
     }
 
     /**
-     * @throws \Throwable
+     * @param array $info
+     * @param array $invlotatt
+     * @param $time
+     * @param $who
+     * @return bool
+     * 更新asn状态
      */
     public function updateFluxAsn(array $info, array $invlotatt, $time, $who): bool
     {
@@ -565,59 +618,67 @@ sql;
                 $asnDetail['customerid'] == $info['customerid'] &&
                 $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 收货数量+已收数量<预期数量
-                $db->update(DB::raw("UPDATE DOC_ASN_DETAILS SET receivedqty = receivedqty + ?,receivedqty_each = receivedqty_each + ?,linestatus = '30',holdrejectcode ='OK',
+//        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 收货数量+已收数量<预期数量
+            $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']]);
+                [(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 收货数量+已收数量=预期数量
+            $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 = ?"),
+                [(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_detail 所有状态都为完全收货是  asn_header 状态修改为 完全收货(asnstatus=40)
+            if (OracleDOCASNDetail::query()->where('asnno', $info['asnno'])->where('linestatus', 40)->count() == $asn->asn_details_count) {
+                $db->update(DB::raw("UPDATE DOC_ASN_HEADER SET asnstatus = '40',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ?"),
+                    [$time, $who, $info['asnno']]);
+            } else {
                 //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 收货数量+已收数量=预期数量
-                $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 = ?"),
-                    [(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_detail 所有状态都为完全收货是  asn_header 状态修改为 完全收货(asnstatus=40)
-                if (OracleDOCASNDetail::query()->where('asnno', $info['asnno'])->where('linestatus', 40)->count() == $asn->asn_details_count) {
-                    $db->update(DB::raw("UPDATE DOC_ASN_HEADER SET asnstatus = '40',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ?"),
-                        [$time, $who, $info['asnno']]);
-                } else {
-                    //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']]);
-                }
             }
-            return true;
-        });
+        }
+        return true;
+//        });
     }
 
     /**
-     * @throws \Throwable
+     * @param array $info
+     * @param $lotNum
+     * @param $who
+     * @param $time
+     * @param array $actTransactionLog
+     * 更新flux 库存
      */
     public function updateFluxInv(array $info, $lotNum, $who, $time, array $actTransactionLog)
     {
         $db = DB::connection("oracle");
-        $db->transaction(function () use ($db, $info, $lotNum, $actTransactionLog, $who, $time) {
-            //更新 inv_lot 批次 库存表
-            $invLot = $db->selectOne(DB::raw("SELECT * FROM INV_LOT WHERE lotnum = ? AND customerid = ? AND sku = ? "), [
-                $lotNum, $info['customerid'], $info['sku']
-            ]);
-            if ($invLot) $db->update(DB::raw("UPDATE INV_LOT SET qty = qty+?,edittime=?,editwho=? WHERE lotnum = ? AND customerid = ? AND sku = ?"), [
+//        $db->transaction(function () use ($db, $info, $lotNum, $actTransactionLog, $who, $time) {
+        //更新 inv_lot 批次 库存表
+        $invLot = $db->selectOne(DB::raw("SELECT * FROM INV_LOT WHERE lotnum = ? AND customerid = ? AND sku = ? FOR UPDATE"), [
+            $lotNum, $info['customerid'], $info['sku']
+        ]);
+        if ($invLot){
+            $db->update(DB::raw("UPDATE INV_LOT SET qty = qty+?,edittime=?,editwho=? WHERE lotnum = ? AND customerid = ? AND sku = ?"), [
                 (int)$info['amount'], $time, $who, $lotNum, $info['customerid'], $info['sku'],
             ]);
-            else $db->insert(DB::raw("INSERT INTO INV_LOT VALUES(?,?,?,?,0,0,0,0,0,0,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?)"), [
+        }else {
+            $db->insert(DB::raw("INSERT INTO INV_LOT VALUES(?,?,?,?,0,0,0,0,0,0,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?)"), [
                 $lotNum, $info['customerid'], $info['sku'], $info['amount'], $time, $who, $time, $who
             ]);
-            //更新 inv_lot_loc_id 批次/库位/跟踪号 库存表
-            $invLotId = $db->selectOne(DB::raw("SELECT * FROM inv_lot_loc_id WHERE lotnum = ? AND locationid = ? AND customerid = ? AND sku = ? AND traceid = ? FOR UPDATE"), [
-                $lotNum, $actTransactionLog['location'], $actTransactionLog['customerid'], $actTransactionLog['sku'], $actTransactionLog['trackid']
-            ]);
+        }
+        //更新 inv_lot_loc_id 批次/库位/跟踪号 库存表
+        $invLotId = $db->selectOne(DB::raw("SELECT * FROM inv_lot_loc_id WHERE lotnum = ? AND locationid = ? AND customerid = ? AND sku = ? AND traceid = ? FOR UPDATE"), [
+            $lotNum, $actTransactionLog['location'], $actTransactionLog['customerid'], $actTransactionLog['sku'], $actTransactionLog['trackid']
+        ]);
 
 //            if ($info['location']) { //存在目标库位
 //                $invLotIdHasPreLocation = $db->selectOne(DB::raw("SELECT * FROM inv_lot_loc_id WHERE lotnum = ? AND locationid = ? AND customerid = ? AND sku = ? AND traceid = ? FOR UPDATE"), [
@@ -643,36 +704,45 @@ sql;
 //                }
 //
 //            }
-                if ($invLotId) $db->update(DB::raw("UPDATE inv_lot_loc_id SET qty = qty+?,qtymvout = qtymvout+?,edittime=?,editwho=? WHERE lotnum = ? AND locationid = ? AND traceid = ?"), [
-                    (int)$info['amount'],(int)$info['amount'], $time, $who, $lotNum, $actTransactionLog['location'], $actTransactionLog['trackid']
-                ]);
-                else $db->insert(DB::raw("INSERT INTO inv_lot_loc_id VALUES(?,?,?,?,?,?,0,0,0,0,?,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,0,0,0,0,0,'*',0,null)"), [
-                    $lotNum, $actTransactionLog['location'], $actTransactionLog['trackid'], $actTransactionLog['customerid'], $actTransactionLog['sku'], (int)$info['amount'], (int)$info['amount'], $time, $who, $time, $who,
-                ]);
-        });
+        if ($invLotId){
+            $db->update(DB::raw("UPDATE inv_lot_loc_id SET qty = qty+?,qtymvout = qtymvout+?,edittime=?,editwho=? WHERE lotnum = ? AND locationid = ? AND traceid = ?"), [
+                (int)$info['amount'], (int)$info['amount'], $time, $who, $lotNum, $actTransactionLog['location'], $actTransactionLog['trackid']
+            ]);
+        }else {
+            $db->insert(DB::raw("INSERT INTO inv_lot_loc_id VALUES(?,?,?,?,?,?,0,0,0,0,?,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,0,0,0,0,0,'*',0,null)"), [
+                $lotNum, $actTransactionLog['location'], $actTransactionLog['trackid'], $actTransactionLog['customerid'], $actTransactionLog['sku'], (int)$info['amount'], (int)$info['amount'], $time, $who, $time, $who,
+            ]);
+        }
+//        });
     }
 
     /**
-     * @throws \Throwable
+     * @param array $info
+     * @param array $invlotatt
+     * @param $actTransactionLog
+     * @param $who
+     * @param $time
+     * @return bool
+     * 生成上架任务
      */
-    public function setFluxTskTaskListPA(array $info, array $invlotatt, $actTransactionLog, $who, $time)
+    public function setFluxTskTaskListPA(array $info, array $invlotatt, $actTransactionLog, $who, $time): bool
     {
         $db = DB::connection("oracle");
-        $db->transaction(function () use ($db, $info, $invlotatt, $actTransactionLog, $who, $time) {
-            $sql = <<<sql
+//        $db->transaction(function () use ($db, $info, $invlotatt, $actTransactionLog, $who, $time) {
+        $sql = <<<sql
 INSERT INTO TSK_TASKLISTS VALUES(?,'1','PA',?,?,'ASN',?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,null,null,?,?,?,?,?,?,?,?,null,null,null,null,
     0,0,0,0,null,?,null,null,null,?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),null,null,?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),'N',null,null,
     ?,?,?,'N',null,?,'*',null,null,null,'N',null,null)
 sql;
-            $db->insert(DB::raw($sql), [
-                $actTransactionLog['tsid'], $actTransactionLog['customerid'], $actTransactionLog['sku'], $actTransactionLog['docno'], $actTransactionLog['doclineno'],
-                $actTransactionLog['lotNum'], $actTransactionLog['packid'], 'EA', $info['amount'], $info['amount'], $actTransactionLog['location'], $actTransactionLog['location'],
-                $actTransactionLog['trackid'], $actTransactionLog['lotNum'], $actTransactionLog['packid'], 'EA', $info['amount'], $info['amount'],
-                $info['location'], $info['location'], $actTransactionLog['trackid'], '00', 'Putaway Task', '3', $invlotatt['lotatt01'], $invlotatt['lotatt02'], $invlotatt['lotatt03'], $invlotatt['lotatt04'],
-                $invlotatt['lotatt05'], $invlotatt['lotatt06'], $invlotatt['lotatt07'], $invlotatt['lotatt08'], $actTransactionLog['trid'], $who, $time, null, null, null, null,
-                $actTransactionLog['userdefine1'], $actTransactionLog['userdefine2'], $actTransactionLog['userdefine3'], $actTransactionLog['warehouseid']
-            ]);
-        });
+        return $db->insert(DB::raw($sql), [
+            $actTransactionLog['tsid'], $actTransactionLog['customerid'], $actTransactionLog['sku'], $actTransactionLog['docno'], $actTransactionLog['doclineno'],
+            $actTransactionLog['lotNum'], $actTransactionLog['packid'], 'EA', $info['amount'], $info['amount'], $actTransactionLog['location'], $actTransactionLog['location'],
+            $actTransactionLog['trackid'], $actTransactionLog['lotNum'], $actTransactionLog['packid'], 'EA', $info['amount'], $info['amount'],
+            $info['location'], $info['location'], $actTransactionLog['trackid'], '00', 'Putaway Task', '3', $invlotatt['lotatt01'], $invlotatt['lotatt02'], $invlotatt['lotatt03'], $invlotatt['lotatt04'],
+            $invlotatt['lotatt05'], $invlotatt['lotatt06'], $invlotatt['lotatt07'], $invlotatt['lotatt08'], $actTransactionLog['trid'], $who, $time, null, null, null, null,
+            $actTransactionLog['userdefine1'], $actTransactionLog['userdefine2'], $actTransactionLog['userdefine3'], $actTransactionLog['warehouseid']
+        ]);
+//        });
     }
 
     /**
@@ -680,48 +750,56 @@ sql;
      * @param $lotNum
      * @param $who
      * @param $time
-     * @return mixed
-     * @throws \Throwable
+     * @return array
      * 创建入库事务
      */
-    public function setFluxActTransactionLog(array $info, $lotNum, $who, $time)
+    public function setFluxActTransactionLog(array $info, $lotNum, $who, $time): array
     {
         $db = DB::connection("oracle");
-        return $db->transaction(function () use ($db, $info, $lotNum, $time, $who) {
-            if ($info['trackNumber']) $trackNumber = $info['trackNumber'];
-            else $trackNumber = substr(md5($time), 0, 30);
-            $asnHeader = OracleDOCASNHeader::query()->where('asnno', $info['asnno'])->first();
-            $asnDetail = OracleDOCASNDetail::query()->where('asnno', $info['asnno'])->where('sku', $info['sku'])->first();
-            $sql = <<<sql
+//        return $db->transaction(function () use ($db, $info, $lotNum, $time, $who) {
+        if ($info['trackNumber']) $trackNumber = $info['trackNumber'];
+        else $trackNumber = substr(md5($time), 0, 30);
+        $asnHeader = OracleDOCASNHeader::query()->where('asnno', $info['asnno'])->first();
+        $asnDetail = OracleDOCASNDetail::query()->where('asnno', $info['asnno'])
+            ->where('asnlineno', $info['asnlineno'])->where('sku', $info['sku'])->first();
+        //添加超收判断
+        $actTransactionLogQty = OracleActTransactionLog::query()->where('docno', $info['asnno'])
+            ->where('status','99')->where('transactiontype','IN')//事务状态,类型限定
+            ->where('doclineno', $info['asnlineno'])->where('fmsku', $info['sku'])->count('fmqty');
+        if ((int)($info['amount'] + $actTransactionLogQty) > (int)$asnDetail['expectedqty']) return [];
+
+        $sql = <<<sql
 INSERT INTO ACT_TRANSACTION_LOG VALUES(?,'IN',?,?,?,?,'ASN',?,?,?,?,?,?,?,?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,
 TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,0,0,0,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,?,null,null,null,?,?,?,?,?,?,?,?,
 ?,?,?,?,'1','Y',null,?,?,?,?,null,null,?,null,null)
 sql;
-            list($trid, $max) = app('StorageService')->getTrNumber();
-            list($tsid, $max) = $this->getTsNum();
-            $db->insert(DB::raw($sql), [
-                $trid, $asnDetail->customerid, $asnDetail->sku,
-                $asnDetail->asnno, $asnDetail->asnlineno, $lotNum, $asnDetail->receivinglocation, '*', $asnDetail->packid, 'EA', $info['amount'], $info['amount'], '99', $time, $who,
-                $time, $who, $time, $asnDetail->customerid, $asnDetail->sku, $trackNumber, $asnDetail->receivinglocation, $who, $asnDetail->packid, 'EA', $info['amount'], $info['amount'], $lotNum,
-                '*', '0', 'N', $tsid, substr($asnDetail->receivinglocation, -4), $asnHeader->userdefine1, $asnHeader->userdefine2,
-                $asnHeader->userdefine3, 'O'
-            ]);
-            app('StorageService')->setTrNumber();
-            $this->setTsNum();
-            $actTransactionLog = [
-                'trid' => $trid, 'docno' => $asnDetail->asnno, 'customerid' => $asnDetail->customerid, 'sku' => $asnDetail->sku, 'doclineno' => $asnDetail->asnlineno, 'lotNum' => $lotNum, 'location' => $asnDetail->receivinglocation,
-                'packid' => $asnDetail->packid, 'tsid' => $tsid, 'warehouseid' => substr($asnDetail->receivinglocation, -4), 'userdefine1' => $asnHeader->userdefine1, 'userdefine2' => $asnHeader->userdefine2,
-                'userdefine3' => $asnHeader->userdefine3, 'trackid' => $trackNumber
-            ];
-            return $actTransactionLog;
-        });
+        list($trid, $max) = app('StorageService')->getTrNumber();
+        list($tsid, $max) = $this->getTsNum();
+        $db->insert(DB::raw($sql), [
+            $trid, $asnDetail->customerid, $asnDetail->sku,
+            $asnDetail->asnno, $asnDetail->asnlineno, $lotNum, $asnDetail->receivinglocation, '*', $asnDetail->packid, 'EA', $info['amount'], $info['amount'], '99', $time, $who,
+            $time, $who, $time, $asnDetail->customerid, $asnDetail->sku, $trackNumber, $asnDetail->receivinglocation, $who, $asnDetail->packid, 'EA', $info['amount'], $info['amount'], $lotNum,
+            '*', '0', 'N', $tsid, substr($asnDetail->receivinglocation, -4), $asnHeader->userdefine1, $asnHeader->userdefine2,
+            $asnHeader->userdefine3, 'O'
+        ]);
+        app('StorageService')->setTrNumber();
+        $this->setTsNum();
+        $actTransactionLog = [
+            'trid' => $trid, 'docno' => $asnDetail->asnno, 'customerid' => $asnDetail->customerid, 'sku' => $asnDetail->sku, 'doclineno' => $asnDetail->asnlineno, 'lotNum' => $lotNum, 'location' => $asnDetail->receivinglocation,
+            'packid' => $asnDetail->packid, 'tsid' => $tsid, 'warehouseid' => substr($asnDetail->receivinglocation, -4), 'userdefine1' => $asnHeader->userdefine1, 'userdefine2' => $asnHeader->userdefine2,
+            'userdefine3' => $asnHeader->userdefine3, 'trackid' => $trackNumber
+        ];
+        return $actTransactionLog;
+//        });
     }
 
     /**
      * @param array $info
+     * @param array $invlotatt
+     * @param $who
+     * @param $time
      * @return mixed
-     * @throws \Throwable
-     * 或去flux 批次号
+     * 获取flux 批次号
      */
     public function getOrCreateLotNum(array $info, array $invlotatt, $who, $time)
     {
@@ -733,18 +811,18 @@ sql;
 
         $db = DB::connection("oracle");
         list($num, $max) = $this->getLtNum();
-        return $db->transaction(function () use ($db, $info, $invlotatt, $num, $who, $time) {
-            $sql = <<<sql
+//        return $db->transaction(function () use ($db, $info, $invlotatt, $num, $who, $time) {
+        $sql = <<<sql
 INSERT INTO INV_LOT_ATT VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,
 TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?)
 sql;
-            $db->insert(DB::raw($sql), [
-                $num, $info['customerid'], $info['sku'], $invlotatt['lotatt01'], $invlotatt['lotatt02'], $invlotatt['lotatt03'], $invlotatt['lotatt04'],
-                $invlotatt['lotatt05'], $invlotatt['lotatt06'], $invlotatt['lotatt07'], $invlotatt['lotatt08'], null, null, null, null, $time, $who, $time, $who, $time, null
-            ]);
-            $this->setLtNum();
-            return $num;
-        });
+        $db->insert(DB::raw($sql), [
+            $num, $info['customerid'], $info['sku'], $invlotatt['lotatt01'], $invlotatt['lotatt02'], $invlotatt['lotatt03'], $invlotatt['lotatt04'],
+            $invlotatt['lotatt05'], $invlotatt['lotatt06'], $invlotatt['lotatt07'], $invlotatt['lotatt08'], null, null, null, null, $time, $who, $time, $who, $time, null
+        ]);
+        $this->setLtNum();
+        return $num;
+//        });
 
     }
 
@@ -795,4 +873,43 @@ sql;
             ->where("name", "flux_ts_number")
             ->update(["value" => DB::raw("value+1")]);
     }
+
+    /**
+     * @param $param
+     * @return array
+     * 获取库存信息
+     */
+    public function getInventoryInfos($param): array
+    {
+        $sql = <<<sql
+select BAS_SKU.SKU,INV_LOT_LOC_ID.CUSTOMERID,BAS_SKU.ALTERNATE_SKU1,INV_LOT_LOC_ID.LOCATIONID,INV_LOT_ATT.LOTATT05,INV_LOT_ATT.LOTATT08,
+       INV_LOT_ATT.LOTATT01,INV_LOT_ATT.LOTATT02,INV_LOT_ATT.LOTATT03,INV_LOT_ATT.LOTATT04,
+       sum(INV_LOT_LOC_ID.QTY) AS QTY from INV_LOT_LOC_ID
+    left join BAS_SKU on INV_LOT_LOC_ID.CUSTOMERID=BAS_SKU.CUSTOMERID and INV_LOT_LOC_ID.SKU =BAS_SKU.SKU
+    left join INV_LOT_ATT on INV_LOT_ATT.LOTNUM=INV_LOT_LOC_ID.LOTNUM where
+sql;
+        if ($this->checkUserOwnerAuth($param)) { //输入条件为货主
+            $sql .= ' INV_LOT_LOC_ID.CUSTOMERID= ?';
+        } else if (preg_match('/^[A-Z]{1,3}[0-9]{2,3}[-][0-9]{2,3}[-][0-9]{2,3}$/', $param) ||strpos($param,'IDE') !== false) { //判断是否为库位
+            $sql .= ' INV_LOT_LOC_ID.LOCATIONID= ?';
+        } else {
+            $sql .= " BAS_SKU.SKU in (  select SKU from BAS_SKU where ALTERNATE_SKU1=? union
+                                        select SKU from BAS_SKU where ALTERNATE_SKU2=? union
+                                        select SKU from BAS_SKU where ALTERNATE_SKU3=? union
+                                        select SKU from BAS_SKU where SKU=? )";
+        }
+
+        $sql .= ' group by BAS_SKU.SKU,INV_LOT_LOC_ID.CUSTOMERID,BAS_SKU.ALTERNATE_SKU1,INV_LOT_LOC_ID.LOCATIONID,
+        INV_LOT_ATT.LOTATT05,INV_LOT_ATT.LOTATT08,INV_LOT_ATT.LOTATT01,INV_LOT_ATT.LOTATT02,INV_LOT_ATT.LOTATT03,INV_LOT_ATT.LOTATT04';
+        if ($this->checkUserOwnerAuth($param)) {
+            $invLots = DB::connection("oracle")->select(DB::raw($sql), [strtoupper($param)
+            ]);
+        }else if(preg_match('/^[A-Z]{1,3}[0-9]{2,3}[-][0-9]{2,3}[-][0-9]{2,3}$/', $param) ||strpos($param,'IDE') !== false){
+            $invLots = DB::connection("oracle")->select(DB::raw($sql), [$param]);
+        } else {
+            $invLots = DB::connection("oracle")->select(DB::raw($sql), [$param, $param, $param, $param]);
+        }
+        if (!$invLots) return [];
+        else return $invLots;
+    }
 }

+ 33 - 0
app/Services/Interfaces/DeliveryInterface.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace App\Services\Interfaces;
+
+
+use Illuminate\Support\Str;
+
+interface DeliveryInterface
+{
+
+    /*
+     *     'type' => 'CAINIAO',              // 需要前台过沟通的组件
+     *     'task_id' => Str::uuid()          // 组件打印任务id
+     *     'is_process' => false,            // is_process 是否已通过自定义模板处理
+     *     'data' => $item['userdefine1'],   // 组件所需要的数据
+     *     'component_type' => 'TB',         // 富勒下发的接口
+     *     'owner_code' => h                 // 货主
+     *     'logistic_code' =>                // 承运商
+     *     'logistic_number' =>              // 快递单号
+     *     'delivery' => $this->getDelivery($item),
+     *     'base64' =>                       // 快递面单的base64编码
+     */
+    function getDeliveryInfo($oracleDocOrderDeliveryInfos);
+
+    function getDelivery($item);
+
+    /**
+     * 获取打印图片的base64编码
+     * @param $item
+     * @return mixed
+     */
+    function getBase64($item);
+}

+ 14 - 0
app/Services/InventoryAccountService.php

@@ -77,21 +77,25 @@ class InventoryAccountService
         $sql.=' , storeStatus.QTY 在库数量, storeStatus.QtyAllocated 占用数量,count(1) over () as sum from ';
         $sql.=' (select FMLotNum,FMSKU,TOCustomerID 客户,0 as 移出数量, sum(TOQty_Each) as 移入数量, TOLocation as 库位 ';
         $sql.=" from ACT_Transaction_Log where TransactionType='PA' ";
+        if ($code)$sql.=" and TOCustomerID = '".$code."' ";
         if ($date_start) $sql.=" and addtime > to_date('".$date_start." 00:00:00','yyyy-mm-dd hh24:mi:ss') ";
         if ($date_end) $sql.=" and addtime < to_date('".$date_end." 23:59:59','yyyy-mm-dd hh24:mi:ss') ";
         $sql.=' group by TOCustomerID, TOLocation,FMSKU,FMLotNum union all ';
         $sql.=' select FMLotNum,FMSKU,FMCUSTOMERID 客户,sum(FMQty_Each) as 移出数量, 0 as 移入数量, FMLOCATION as 库位 ';
         $sql.=" from ACT_Transaction_Log where TransactionType='SO' ";
+        if ($code)$sql.=" and FMCUSTOMERID = '".$code."' ";
         if ($date_start) $sql.=" and addtime > to_date('".$date_start." 00:00:00','yyyy-mm-dd hh24:mi:ss') ";
         if ($date_end) $sql.=" and addtime < to_date('".$date_end." 23:59:59','yyyy-mm-dd hh24:mi:ss') ";
         $sql.=' group by FMCustomerID, FMLocation,FMSKU,FMLotNum union all ';
         $sql.=' select FMLotNum,FMSKU,FMCUSTOMERID 客户,sum(FMQty_Each) as 移出数量,0 as 移入数量, FMLocation as 库位 ';
         $sql.=" from ACT_Transaction_Log  where TransactionType='MV' ";
+        if ($code)$sql.=" and FMCUSTOMERID = '".$code."' ";
         if ($date_start) $sql.=" and addtime > to_date('".$date_start." 00:00:00','yyyy-mm-dd hh24:mi:ss') ";
         if ($date_end) $sql.=" and addtime < to_date('".$date_end." 23:59:59','yyyy-mm-dd hh24:mi:ss') ";
         $sql.=' group by FMLocation,FMCUSTOMERID,FMSKU,FMLotNum union all ';
         $sql.=' select FMLotNum,FMSKU,TOCustomerID 客户,0 as 移出数量,sum(TOQty_Each)as 移入数量, TOLocation as 库位 ';
         $sql.=" from ACT_Transaction_Log where TransactionType='MV' ";
+        if ($code)$sql.=" and TOCustomerID = '".$code."' ";
         if ($date_start) $sql.=" and addtime > to_date('".$date_start." 00:00:00','yyyy-mm-dd hh24:mi:ss') ";
         if ($date_end) $sql.=" and addtime < to_date('".$date_end." 23:59:59','yyyy-mm-dd hh24:mi:ss') ";
         $sql.=' group by TOLocation,TOCustomerID,FMSKU,FMLotNum)stockLog ';
@@ -211,7 +215,17 @@ class InventoryAccountService
             if ($location||$barcode)$type='局部盘点';
             if (!$location&&!$barcode)$type='动盘';
             $wmsInventories=$this->conditionPortStock($date_start,$date_end,$ownerId,$location,$barcode);
+            //动盘  判断库存为0的ide料想是否放有其他商品
+            foreach ($wmsInventories as $key=>$wmsInventory){
+                if (!$wmsInventory->在库数量 && strpos($wmsInventory->库位,'IDE') !== false){
+                    /** @var HandInStorageService $handInStorageService  */
+                    $handInStorageService=app('HandInStorageService');
+                    $invs=$handInStorageService->getInventoryInfos($wmsInventory->库位);
+                    if (count($invs)>0) unset($wmsInventories[$key]);
+                }
+            }
         }
+
         if (!$date_start&&!$date_end){
             $ownerName=Owner::where('id',$ownerId)->value('code');
             //$ownerName=OracleBasCustomer::where('customer_type','OW')->where('active_flag','Y')->where('descr_c',$name)->value('customerid');

+ 95 - 0
app/Services/JDDeliveryService.php

@@ -0,0 +1,95 @@
+<?php
+
+namespace App\Services;
+
+use App\OracleDocOrderDeliveryInfo;
+use App\OracleDOCOrderHeader;
+use App\OwnerLogisticPrintTemplate;
+use App\Services\Interfaces\DeliveryInterface;
+use App\Traits\DeliveryProcess;
+use App\Traits\DrawImage;
+use Illuminate\Database\Query\Builder;
+use Illuminate\Support\Str;
+
+class JDDeliveryService implements DeliveryInterface
+{
+    use DeliveryProcess;
+
+    function getDeliveryInfo($logistic_number): array
+    {
+        $oracleDocOrderHeaders = OracleDOCOrderHeader::query()
+            ->with('oracleBASCustomer','oracleDOCWaveDetail')
+            ->whereIn('deliveryno',$logistic_number)
+            ->whereIn('consigneeId',['JD','BSZX','BSZFC','BSZXDF','BSZFCDF'])
+            ->get();
+        return $oracleDocOrderHeaders->map(function ($item){
+            return [
+                'type' => 'JD',
+                'is_process' => true,
+                'task_id' => Str::uuid(),
+                'data' => '',
+                'component_type' => 'JD',
+                'owner_code' => $item->customerid ?? '',
+                'logistic_code' => $item->userdefine1 ?? '',
+                'logistic_number' => $item['deliveryno'],
+                'delivery' => null,
+                'base64' => $this->getBase64($item),
+                'printerName' => '',
+            ];
+        })->toArray();
+    }
+
+    public function getBase64($item): string
+    {
+        $printTemplate = OwnerLogisticPrintTemplate::query()->with('printTemplate')->where('owner_id', function(Builder $query)use($item){
+            $query->from("owners")->selectRaw('id')->where("code",$item['customerid']);
+        })->where('logistic_id', function(Builder $query)use($item){
+            $query->from("logistics")->selectRaw('id')->where("code",$item['userdefine1']);
+        })->first();
+
+        $delivery = $this->getDelivery($item);
+
+        $image = $this->draw($delivery,$printTemplate->printTemplate ?? null,null);
+
+        if (!$image) return '';
+
+        $path = '';
+
+        $this->saveImage($image,$path);
+
+        return $this->readImageBase64($path);
+    }
+
+    /*
+     * 订单号
+     * 波次号
+     * 运单号
+     * 店铺
+     * 商家联系号
+     * 商家订单号
+     * 发货地址,省,市区
+     *
+     * 发货分拣中心
+     * 发货人
+     * 发货人号码
+     * 收货地址
+     * 收货分拣中心
+     * 收件人
+     * 商品
+     * 备注
+     *
+     */
+
+    function getDelivery($item): array
+    {
+        $delivery = $this->getDocOrderInfo($item);
+        $delivery['b_addresss1'] = $item['MJ-ZP'];
+        $delivery['d_addresss1'] = $item['BB-Y3-21'];
+        return $delivery;
+    }
+
+    function processing(&$params)
+    {
+        return null;
+    }
+}

+ 27 - 0
app/Services/LaborCompanyService.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Services;
+
+use App\Role;
+use App\Traits\ServiceAppAop;
+use App\LaborCompany;
+use Illuminate\Support\Facades\DB;
+
+class LaborCompanyService
+{
+    use ServiceAppAop;
+    protected $modelClass=LaborCompany::class;
+
+    public function createRole($laborCompany)
+    {
+       $role=Role::query()->firstOrCreate(['name'=>$laborCompany->name]);
+       DB::table('role_labor_company')->updateOrInsert(['role_id'=>$role->id,'labor_company_id'=>$laborCompany->id]);
+    }
+
+    public function updateRole($laborCompany)
+    {
+        $role_id=DB::table('role_labor_company')->where('labor_company_id',$laborCompany->id)->value('role_id');
+        Role::query()->where('id',$role_id)->update(['name'=>$laborCompany->name]);
+    }
+
+}

+ 3 - 14
app/Services/LogisticAliJiSuApiService.php

@@ -46,8 +46,6 @@ class LogisticAliJiSuApiService
         if (!isset($response)||($response && $response->status!=0)) {
             return [
                 'logistic_number' => $logistic_number,
-                'exception_type' => '揽件异常',
-                'exception' => '是',
             ];
         }
         else {
@@ -60,25 +58,16 @@ class LogisticAliJiSuApiService
             if (!empty($list) && is_array($list)) {
                 $lastNativeRoute = $list[0];
                 $result['status'] = $this->getStatus($response);
-                if ($result['status'] == '已收') $result['received_at'] = $lastNativeRoute->time;
+                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);
-                $result['exception_type'] = $exceptionData['exception_type'];
-                $result['exception'] = $exceptionData['exception'];
 
             } else {
                 $result['status'] = null;
                 $result['transfer_status'] = [];
             }
-            if (!array_key_exists('exception', $result)
-                && !array_key_exists('exception_type', $result)
-                && array_key_exists('transfer_status', $result)
-            ) {
-                $result['exception_type'] = '无';
-                $result['exception'] = '否';
-            }
             if (!array_key_exists('status', $result)) {
                 $result['status'] = null;
                 $result['transfer_status'] = [];
@@ -101,13 +90,13 @@ class LogisticAliJiSuApiService
                 $status = '派送中';
                 break;
             case '3':
-                $status = '已收';
+                $status = '已收';
                 break;
             case '4':
                 $status = '派送异常';
                 break;
             default:
-                $status = '';
+                $status = '其他';
         }
         return $status;
     }

+ 5 - 23
app/Services/LogisticSFService.php

@@ -104,20 +104,6 @@ xml;
             $lastRoute = get_object_vars($routeResponse['Route'][count($routeResponse['Route']) - 1])['@attributes'];//获取最新的路由信息
             $data = $this->switchOpCodeToStatus($lastRoute, $data);
             $data['transfer_status'] = $this->transformRoutes($routeResponse['Route']);
-            if (!array_key_exists('exception', $data)) {//当顺丰返回异常时,不需要再根据时间判断是否异常,直接用顺丰的异常就好
-                $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
-                $exceptionData = $orderPackageReceivedSyncService->setExceptionType($data, array_key_exists('accept_time',$lastRoute) ? $lastRoute['accept_time'] : null);
-                $data['exception_type'] = $exceptionData['exception_type'];
-                $data['exception'] = $exceptionData['exception'];
-            }
-            //如果没有发现额外的异常,且查询到物流轨迹,将异常置为无
-            if (!array_key_exists('exception', $data)
-                && !array_key_exists('exception_type', $data)
-                && array_key_exists('transfer_status', $data)
-            ) {
-                $data['exception_type'] = '无';
-                $data['exception'] = '否';
-            }
         } catch (Exception $e) {
             throw new WarningException("单号没有查询到快递路由信息','LogisticSFService->transformSFOneToArr->{$data['logistic_number']}");
         } finally {
@@ -139,9 +125,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;
@@ -168,8 +154,6 @@ xml;
                     break;
                 case 33:
                     $data['status'] = '派送异常';
-                    $data['exception_type'] = '派件异常';
-                    $data['exception'] = '是';
                     break;
                 case 204:
                 case 44:
@@ -181,7 +165,7 @@ xml;
                 case 607:
                 case 8000:
                 case 80:
-                    $data['status'] = '已收';
+                    $data['status'] = '已收';
                     $data['received_at'] = $lastRoute[$this->protected_switch['received_at']];
                     break;
                 case 648:
@@ -189,9 +173,7 @@ xml;
                     $data['status'] = '返回中';
                     break;
                 case 70:
-                    $data['status'] = '无';
-                    $data['exception'] = '是';
-                    $data['exception_type'] = '其他';
+                    $data['status'] = '其他';
                     break;
                 default:
                     throw new WarningException("未知的丰桥状态码: {$lastRoute['opcode']}->{json_encode($lastRoute)}");

+ 5 - 21
app/Services/LogisticYDService.php

@@ -98,11 +98,9 @@ class LogisticYDService
 
     public function format($nativeResponse, $logistic_number)
     {
-        if (is_null($nativeResponse) || $nativeResponse->code != '0000' || $nativeResponse->data->result == "false") {
+        if (is_null($nativeResponse) || $nativeResponse->code != '0000' || empty($nativeResponse->data) ||$nativeResponse->data->result == "false") {
             return [
                 'logistic_number' => $logistic_number,
-                'exception_type' => '揽件异常',
-                'exception' => '是',
             ];
         } else {
             $nativeData = $nativeResponse->data;
@@ -116,33 +114,19 @@ class LogisticYDService
             if (!empty($nativeRoutes)) {
                 $lastNativeRoute = $nativeRoutes[count($nativeRoutes) - 1];
                 $result['status'] = $this->getStatus($nativeData);
-                if ($result['status'] == '已收') {
+                if ($result['status'] == '已收') {
                     $result['received_at'] = $lastNativeRoute->time;
                 }
                 $result['transfer_status'] = $this->getTransferStatus($nativeRoutes);
                 $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);
-                $result['exception_type'] = $exceptionData['exception_type'];
-                $result['exception'] = $exceptionData['exception'];
-
             } else {
                 $result['status'] = null;
                 $result['transfer_status'] = [];
             }
-
             if (!array_key_exists('status', $result)) {
                 $result['status'] = null;
                 $result['transfer_status'] = [];
             }
-            //如果没有发现额外的异常,且查询到物流轨迹,将异常置为无
-            if (!array_key_exists('exception', $result)
-                && !array_key_exists('exception_type', $result)
-                && array_key_exists('transfer_status', $result)
-            ) {
-                $result['exception_type'] = '无';
-                $result['exception'] = '否';
-            }
             return $result;
         }
     }
@@ -162,16 +146,16 @@ class LogisticYDService
                 $status = '在途';
                 break;
             case 'SIGNED':
-                $status = '已收';
+                $status = '已收';
                 break;
             case 'RETURN':
                 $status = '返回中';
                 break;
             case 'SIGNFAIL':
-                $status = '';
+                $status = '其他';
                 break;
             default:
-                $status = '';
+                $status = '其他';
         }
         return $status;
     }

+ 3 - 14
app/Services/LogisticYTOService.php

@@ -47,8 +47,6 @@ class LogisticYTOService
         if (is_object($response) && $response->code=='1001') {
             return [
                 'logistic_number' => $logistic_number,
-                'exception_type' => '揽件异常',
-                'exception' => '是',
             ];
         }
         else {
@@ -58,30 +56,21 @@ class LogisticYTOService
                 LogService::log(LogisticYTOService::class, "YTO快递信息异常", $logistic_number);
                 return [
                     'logistic_number' => $logistic_number,
-                    'exception_type' => '其他',
-                    'exception' => '是',
                 ];
             }
             if (!empty($response) && is_array($response)) {
                 $lastNativeRoute = $response[count($response) - 1];
                 $result['status'] = $this->getStatus($lastNativeRoute);
-                if ($result['status'] == '已收') $result['received_at'] = $lastNativeRoute->upload_Time;
+                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);
-                $result['exception_type'] = $exceptionData['exception_type'];
-                $result['exception'] = $exceptionData['exception'];
             } else {
                 $result['status'] = null;
                 $result['transfer_status'] = [];
             }
             if (!array_key_exists('status', $result)) {$result['status'] = null;$result['transfer_status'] = [];}
-            //如果没有发现额外的异常,且查询到物流轨迹,将异常置为无
-            if (!array_key_exists('exception', $result)
-                && !array_key_exists('exception_type', $result)
-                && array_key_exists('transfer_status', $result)
-            ) {$result['exception_type'] = '无';$result['exception'] = '否';}
             return $result;
         }
     }
@@ -106,13 +95,13 @@ class LogisticYTOService
                 $status = '派送中';
                 break;
             case 'SIGNED':
-                $status = '已收';
+                $status = '已收';
                 break;
             case 'TMS_RETURN':
                 $status = '返回中';
                 break;
             default:
-                $status = '';
+                $status = '其他';
         }
         return $status;
     }

+ 5 - 16
app/Services/LogisticZopService.php

@@ -30,35 +30,24 @@ class LogisticZopService implements LogisticRouteInterface
 
     public function format($nativeResponse,$logistic_number)
     {
+
         $order_package = OrderPackage::query()->where('logistic_number', $logistic_number)->first();
         $result = [
             'logistic_number' => $logistic_number,
-            'exception_type' => $order_package->exception_type,
-            'exception' => $order_package->exception,
             'status' => $order_package->status,
             'transfer_status' => $order_package->transfer_status,
             'received_at' => $order_package->received_at,
         ];
-        $nativeRoutes = $nativeResponse->result??[];
-        if (empty($nativeRoutes)) {
-            $result['exception_type'] = '揽件异常';
-            $result['exception'] = '是';
+        if (empty($nativeResponse->result)|| !$nativeResponse->status || $nativeResponse->statusCode=='P-OW005') {
             return $result;
         }
+        $nativeRoutes = $nativeResponse->result??[];
         $lastRoute = $nativeRoutes[count($nativeRoutes) - 1]??[];
         list($status, $received_at) = $this->getNormalStatusAndReceivedAt($lastRoute);
         $result['status'] = $status;
         $result['received_at'] = $received_at;
         $result['transfer_status'] = $this->getTransferStatus($nativeRoutes);
         $result['routes_length'] = count($result['transfer_status']);
-        /**
-         * @var $orderPackageReceivedSyncService OrderPackageReceivedSyncService
-         */
-        $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
-        $lastRouteDate = Carbon::parse($lastRoute->scanDate / 1000)->addHours(8)->toDateTimeString();
-        $exceptionData = $orderPackageReceivedSyncService->setExceptionType($result, $lastRouteDate);
-        $result['exception_type'] = $exceptionData['exception_type'];
-        $result['exception'] = $exceptionData['exception'];
         return $result;
     }
 
@@ -83,11 +72,11 @@ class LogisticZopService implements LogisticRouteInterface
                 break;
             case 'SIGNED':
             case '签收':
-                $status = '已收';
+                $status = '已收';
                 $received_at = Carbon::parse($lastRoute->scanDate / 1000)->addHours(8)->toDateTimeString();
                 break;
             default:
-                $status = '';
+                $status = '其他';
                 break;
         }
         return array($status, $received_at);

+ 35 - 0
app/Services/MeasureMonitorService.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+
+require_once '../app/library/baidu-api-speech/AipSpeech.php';
+
+class MeasureMonitorService
+{
+    use ServiceAppAop;
+
+    public function getMp3Audio($content): array
+    {
+        if (!$content)$content='空';
+        if (file_exists("storage/".$content.'.mp3')){
+            return ['success' => true,'data' =>['name'=>$content,'path' =>"/storage/".$content.'.mp3'] ];
+        }
+
+        $client=new \AipSpeech(config('api.baidu.speech.APP_ID'),config('api.baidu.speech.API_KEY'),config('api.baidu.speech.SECRET_KEY'));
+        $client->setConnectionTimeoutInMillis('180000');
+        $client->setSocketTimeoutInMillis('180000');
+
+        $result = $client->synthesis($content, 'zh', 1, array(
+            'vol' => 15,
+        ));
+
+        if(!is_array($result)){
+            file_put_contents('storage/'.$content.'.mp3', $result);
+        }
+
+        return  ['success' => true,'data' =>['name'=>$content,'path' =>"/storage/".$content.'.mp3'] ];
+    }
+
+}

+ 49 - 0
app/Services/OrderIssueService.php

@@ -44,6 +44,42 @@ class OrderIssueService
         }
     }
 
+    /**
+     * 生成问题件
+     * @param  array $params
+     * @return array|false[]
+     */
+    public function buildOrderIssue(array $params): array
+    {
+        $data = Carbon::now();
+        foreach ($params as $param){
+            $inner_params[] = [
+                'order_id' => $param['order_id'],
+                'result_explain'=> $param['result_explain'] ?? '',
+                'imported_status'=> $param['imported_status'] ?? '正常',
+                'custom_code'=> $param['custom_code'] ?? null ,
+                'hidden_tag'=> $param['hidden_tag'] ?? null,
+                'order_issue_type_id' => $param['order_issue_type_id'] ?? '',
+                'created_at' => $data,
+                'updated_at' => $data,
+            ];
+        }
+        if (!isset($inner_params)) return ['success' => false];
+        $bool = OrderIssue::query()->insert($inner_params);
+        if (!$bool) return ['success' => false,'message' => '创建问题件异常'];
+        $ordersIssues = OrderIssue::query()->whereIn('order_id', data_get($inner_params, '*.order_id'))->get();
+        event(new AddOrUpdateOrderIssues(data_get($ordersIssues,'*.order_id')));
+        $this->同步退单状态($ordersIssues);
+        $param = [
+            'ids' => data_get($ordersIssues, '*.id'),
+            'content' => '',
+            'user_id' => Auth::user()['id'],
+            'type' => '创建'
+        ];
+        app(OrderIssueProcessLogService::class)->create($param);
+        return ['success' => true];
+    }
+
     public function createOrderIssueByWmsOrder($orderHeaders, $order_issue_type_id, $result_explain, $imported_status = '正常', $custom_code = null,$hiddenTag = null)
     {
         /** @var OrderService $orderService */
@@ -392,4 +428,17 @@ class OrderIssueService
             $orderIssue->update($updateParams);
         });
     }
+
+    /**
+     * 快递单对应的问题件是否存在
+     * @param $logistic_number
+     * @return bool
+     */
+    public function isExists($logistic_number): bool
+    {
+        $order_package_query = OrderPackage::query()->select('order_id')->whereIn('logistic_number',[$logistic_number]);
+        $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() ;
+    }
 }
+

Some files were not shown because too many files changed in this diff