Browse Source

Merge branch 'master' into zengjun

ajun 4 years ago
parent
commit
d4b0647570
100 changed files with 4884 additions and 1248 deletions
  1. 1 0
      .gitignore
  2. 0 0
      .htaccess
  3. 5 0
      app/CommodityMaterialBoxModel.php
  4. 4 1
      app/DischargeTask.php
  5. 61 0
      app/Events/SettlementBillCreateEvent.php
  6. 96 0
      app/Filters/RequirementFilters.php
  7. 0 39
      app/Http/Controllers/CacheShelfController.php
  8. 35 39
      app/Http/Controllers/ControlPanelController.php
  9. 84 0
      app/Http/Controllers/HandInStorageController.php
  10. 8 0
      app/Http/Controllers/HomeController.php
  11. 12 34
      app/Http/Controllers/LogisticController.php
  12. 66 0
      app/Http/Controllers/MaterialBoxModelController.php
  13. 1 1
      app/Http/Controllers/MenuController.php
  14. 153 0
      app/Http/Controllers/OwnerFeeTotalController.php
  15. 0 108
      app/Http/Controllers/OwnerLogisticFeeDetailController.php
  16. 17 0
      app/Http/Controllers/OwnerSundryFeeDetailsController.php
  17. 85 0
      app/Http/Controllers/OwnerWayBillFeeDetailController.php
  18. 24 0
      app/Http/Controllers/OwnerWaybillSettlementBillController.php
  19. 100 0
      app/Http/Controllers/RequirementController.php
  20. 85 0
      app/Http/Controllers/RequirementUserController.php
  21. 67 0
      app/Http/Controllers/SettlementBillExpressFeeDetailController.php
  22. 7 36
      app/Http/Controllers/SettlementBillExpressFeeReportController.php
  23. 66 0
      app/Http/Controllers/SettlementBillLogisticFeeController.php
  24. 66 0
      app/Http/Controllers/SettlementBillPackingMaterialFeeController.php
  25. 65 0
      app/Http/Controllers/SettlementBillProcessFeeController.php
  26. 26 47
      app/Http/Controllers/SettlementBillStorageFeeController.php
  27. 69 0
      app/Http/Controllers/SettlementBillStoreFeeDetailController.php
  28. 93 0
      app/Http/Controllers/SettlementBillStoreFeeReportController.php
  29. 58 0
      app/Http/Controllers/SettlementBillStoreOutFeeDetailController.php
  30. 87 0
      app/Http/Controllers/SettlementBillStoreOutFeeReportController.php
  31. 80 0
      app/Http/Controllers/SettlementBillSundryFeeController.php
  32. 62 0
      app/Http/Controllers/SettlementBillUnloadFeeController.php
  33. 54 0
      app/Http/Controllers/SettlementIndemnityFeeController.php
  34. 57 73
      app/Http/Controllers/StationController.php
  35. 243 82
      app/Http/Controllers/StorageController.php
  36. 4 7
      app/Http/Controllers/StoreController.php
  37. 10 378
      app/Http/Controllers/TestController.php
  38. 77 8
      app/Http/Controllers/WaybillController.php
  39. 17 11
      app/Http/Controllers/api/thirdPart/flux/WaybillController.php
  40. 2 1
      app/Http/Controllers/api/thirdPart/haiq/HaiRoboticsController.php
  41. 2 14
      app/Http/Controllers/api/thirdPart/haiq/LightController.php
  42. 9 0
      app/Http/Controllers/api/thirdPart/jianshang/RejectedController.php
  43. 14 6
      app/Http/Middleware/LogPostRequest.php
  44. 39 0
      app/Http/Requests/RequirementRequest.php
  45. 31 0
      app/Interfaces/SettlementBillControllerInterface.php
  46. 32 0
      app/Interfaces/SettlementBillDetailInterface.php
  47. 41 0
      app/Interfaces/SettlementBillReportInterface.php
  48. 87 12
      app/Jobs/CacheShelfTaskJob.php
  49. 52 0
      app/Jobs/SettlementBillCountingTask.php
  50. 66 0
      app/Jobs/SettlementBillReportTask.php
  51. 37 0
      app/Listeners/SettlementBillCreateListener.php
  52. 14 1
      app/Logistic.php
  53. 5 0
      app/MaterialBox.php
  54. 22 0
      app/MaterialBoxCommodity.php
  55. 6 0
      app/MaterialBoxModel.php
  56. 21 0
      app/OracleBasLotId.php
  57. 5 1
      app/OracleBasSKU.php
  58. 0 1
      app/OracleDOCASNHeader.php
  59. 3 1
      app/Owner.php
  60. 10 9
      app/OwnerBillReportArchive.php
  61. 12 2
      app/OwnerFeeDetail.php
  62. 45 0
      app/OwnerFeeTotal.php
  63. 31 2
      app/OwnerLogisticFeeDetail.php
  64. 15 1
      app/OwnerLogisticFeeReport.php
  65. 3 0
      app/OwnerMaterial.php
  66. 1 1
      app/OwnerPriceOperationItem.php
  67. 74 0
      app/OwnerStoreFeeDetail.php
  68. 46 0
      app/OwnerStoreFeeReport.php
  69. 69 0
      app/OwnerStoreOutFeeDetail.php
  70. 42 0
      app/OwnerStoreOutFeeReport.php
  71. 49 0
      app/OwnerWayBillFeeDetail.php
  72. 37 0
      app/Policies/RequirementPolicy.php
  73. 32 4
      app/Providers/AppServiceProvider.php
  74. 1 0
      app/Providers/AuthServiceProvider.php
  75. 3 0
      app/Providers/EventServiceProvider.php
  76. 79 0
      app/Requirement.php
  77. 18 0
      app/RequirementUser.php
  78. 6 22
      app/Services/BatchService.php
  79. 26 158
      app/Services/CacheShelfService.php
  80. 5 6
      app/Services/CommodityMaterialBoxModelService.php
  81. 79 40
      app/Services/DbOpenService.php
  82. 6 38
      app/Services/ForeignHaiRoboticsService.php
  83. 393 0
      app/Services/HandInStorageService.php
  84. 5 1
      app/Services/LogisticSFService.php
  85. 39 0
      app/Services/MaterialBoxModelService.php
  86. 20 25
      app/Services/MaterialBoxService.php
  87. 2 5
      app/Services/NewOrderCountingRecordService.php
  88. 1 0
      app/Services/OrderCommodityService.php
  89. 2 1
      app/Services/OrderPackageReceivedSyncService.php
  90. 21 7
      app/Services/OwnerBillReportArchiveService.php
  91. 74 0
      app/Services/OwnerDischargeTaskSettlementBillService.php
  92. 465 0
      app/Services/OwnerFeeTotalService.php
  93. 27 15
      app/Services/OwnerLogisticFeeDetailService.php
  94. 82 8
      app/Services/OwnerLogisticFeeReportService.php
  95. 2 2
      app/Services/OwnerPriceOperationService.php
  96. 72 0
      app/Services/OwnerProcessSettlementBillService.php
  97. 127 0
      app/Services/OwnerProcurementSettlementBillService.php
  98. 61 0
      app/Services/OwnerStoreFeeDetailService.php
  99. 172 0
      app/Services/OwnerStoreFeeReportService.php
  100. 97 0
      app/Services/OwnerStoreOutFeeDetailService.php

+ 1 - 0
.gitignore

@@ -32,3 +32,4 @@ yarn-error.log
 /serves/excelExportGo/logs
 /serves/excelExportGo/logs
 /serves/excelExportGo/go_build_main_go.exe
 /serves/excelExportGo/go_build_main_go.exe
 /laravel-echo-server.lock
 /laravel-echo-server.lock
+/database/data

+ 0 - 0
.htaccess


+ 5 - 0
app/CommodityMaterialBoxModel.php

@@ -16,4 +16,9 @@ class CommodityMaterialBoxModel extends Model
     protected $fillable=[
     protected $fillable=[
         "commodity_id","material_box_model_id","maximum"
         "commodity_id","material_box_model_id","maximum"
     ];
     ];
+
+    public function materialBoxModel()
+    {
+        return $this->belongsTo(MaterialBoxModel::class,"material_box_model_id","id");
+    }
 }
 }

+ 4 - 1
app/DischargeTask.php

@@ -61,5 +61,8 @@ class DischargeTask extends Model
         return $this->belongsTo(Warehouse::class);
         return $this->belongsTo(Warehouse::class);
     }
     }
 
 
-
+    public function getTypeAttribute($index)
+    {
+        return $this::types[$index];
+    }
 }
 }

+ 61 - 0
app/Events/SettlementBillCreateEvent.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace App\Events;
+
+use App\OwnerLogisticFeeDetail;
+use App\OwnerStoreFeeDetail;
+use App\OwnerStoreOutFeeDetail;
+use App\OwnerWayBillFeeDetail;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+
+class SettlementBillCreateEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+    //快递费
+    const OWNER_LOGISTIC_FEE_DETAIL = OwnerLogisticFeeDetail::class;
+    //入库费
+    const OWNER_STORE_FEE_DETAIL = OwnerStoreFeeDetail::class;
+    //出库
+    const OWNER_STORE_OUT_FEE_DETAIL = OwnerStoreOutFeeDetail::class;
+    //物流费
+    const OWNER_WAY_BILL_FEE_DETAIL = OwnerWayBillFeeDetail::class;
+
+    public $createData;
+
+    /**
+     * OWNER_LOGISTIC_FEE_DETAIL
+     * OWNER_STORE_FEE_DETAIL
+     * OWNER_STORE_OUT_FEE_DETAIL
+     * OWNER_WAY_BILL_FEE_DETAIL
+     */
+    public $modelName;
+
+    /**
+     * SettlementBillCreateEvent constructor.
+     * @param array $createData
+     * @param string $modelName
+     */
+    public function __construct(array $createData, string $modelName)
+    {
+        $this->createData = $createData;
+        $this->modelName = $modelName;
+    }
+
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 96 - 0
app/Filters/RequirementFilters.php

@@ -0,0 +1,96 @@
+<?php
+
+
+namespace App\Filters;
+
+use App\Order;
+use App\RequirementUser;
+use App\Services\UserService;
+use Illuminate\Http\Request;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Str;
+use phpDocumentor\Reflection\Types\Boolean;
+
+class RequirementFilters
+{
+    protected $request;
+    protected $queryBuilder;
+    protected $filters = [
+        'title',
+        'creator_id',
+        'worker_ids',
+        'began_at_start',
+        'began_at_end',
+        'finished_at_start',
+        'finished_at_end',
+        'created_at_start',
+        'created_at_end',
+    ];
+
+    public function __construct(Request $request)
+    {
+        $this->request = $request;
+    }
+
+    public function apply($builder)
+    {
+        $this->queryBuilder = $builder;
+        $filters = array_filter($this->request->only($this->filters));
+        foreach ($filters as $filter => $value) {
+            if (method_exists($this, $filter)) {
+                $this->$filter($value, $this->queryBuilder);
+            }
+        }
+        return $this->queryBuilder;
+    }
+
+    public function creator_id($creator_id)
+    {
+        $this->queryBuilder->where('user_id', $creator_id);
+    }
+
+    private function worker_ids($worker_ids)
+    {
+        if (strpos($worker_ids, ',') || strpos($worker_ids, ',') || strpos($worker_ids, ' ')) {
+            $arr = array_filter(preg_split('/[,, ]+/is', $worker_ids));
+            $this->queryBuilder->whereIn('id', RequirementUser::query()->select('requirement_id')->whereIn('user_id', $arr));
+        } else {
+            $this->queryBuilder->whereIn('id', RequirementUser::query()->select('requirement_id')->where('user_id', $worker_ids));
+        }
+    }
+
+    public function began_at_start($began_at_start)
+    {
+        $this->queryBuilder->where('begin_at', '>=', \Carbon\Carbon::parse($began_at_start)->startOfDay());
+    }
+
+    public function began_at_end($began_at_end)
+    {
+        $this->queryBuilder->where('begin_at', '<=', \Carbon\Carbon::parse($began_at_end)->endOfDay());
+    }
+
+    public function finished_at_start($finished_at_start)
+    {
+        $this->queryBuilder->where('finished_at', '>=', \Carbon\Carbon::parse($finished_at_start)->startOfDay());
+    }
+
+    public function finished_at_end($finished_at_end)
+    {
+        $this->queryBuilder->where('finished_at', '<=', \Carbon\Carbon::parse($finished_at_end)->endOfDay());
+    }
+
+    public function created_at_start($created_at_start)
+    {
+        $this->queryBuilder->where('created_at', '>=', \Carbon\Carbon::parse($created_at_start)->startOfDay());
+    }
+
+    public function created_at_end($created_at_end)
+    {
+        $this->queryBuilder->where('created_at', '<=', \Carbon\Carbon::parse($created_at_end)->endOfDay());
+    }
+
+    public function title($title)
+    {
+        $this->queryBuilder->where('title', 'like', $title.'%');
+    }
+}

+ 0 - 39
app/Http/Controllers/CacheShelfController.php

@@ -3,12 +3,10 @@
 namespace App\Http\Controllers;
 namespace App\Http\Controllers;
 
 
 use App\Components\AsyncResponse;
 use App\Components\AsyncResponse;
-use App\Services\CacheShelfService;
 use App\Station;
 use App\Station;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\View\Factory;
 use Illuminate\Contracts\View\Factory;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Builder;
-use Illuminate\Http\Request;
 use Illuminate\View\View;
 use Illuminate\View\View;
 
 
 class CacheShelfController extends Controller
 class CacheShelfController extends Controller
@@ -29,41 +27,4 @@ class CacheShelfController extends Controller
         return view('station.cachingShelf.list.index', compact('stations'));
         return view('station.cachingShelf.list.index', compact('stations'));
     }
     }
 
 
-    /**
-     * 获取缓存货架上的料箱
-     * @param Request $request
-     * @param string $id
-     * @param CacheShelfService $service
-     */
-    public function getChildStationApi(Request $request,string $id,CacheShelfService $service)
-    {
-        $stations = $service->getChildStation($id);
-        $this->success($stations);
-    }
-
-    /**
-     * 缓存架亮灯
-     * @param Request $request
-     * @param CacheShelfService $service
-     * @return mixed
-     */
-    public function lightOnApi(Request $request,CacheShelfService $service): array
-    {
-        if($request['stationCode'] && $request['materialBoxCode']){
-            return  $service->bindMaterialBox($request['stationCode'],$request['materialBoxCode']);
-        }
-        return ['success' => false,'message' => '参数错误'];
-    }
-
-    /**
-     * @param Request $request
-     * @param CacheShelfService $service
-     * @return array|bool[]
-     */
-    public function clearTaskApi(Request $request,CacheShelfService $service): array
-    {
-        $code = $request['station'];
-        return $service->clearTask($code);
-    }
-
 }
 }

+ 35 - 39
app/Http/Controllers/ControlPanelController.php

@@ -36,9 +36,9 @@ class ControlPanelController extends Controller
     {
     {
         $ownerIds = $this->getCountingOwnerIds(null);
         $ownerIds = $this->getCountingOwnerIds(null);
         $menus = app(CheckActiveMenuService::class)->activeMenus();
         $menus = app(CheckActiveMenuService::class)->activeMenus();
-        $owners=Owner::query()->whereIn('id',$ownerIds)->get();
+        $owners = Owner::query()->whereIn('id', $ownerIds)->get();
         $warehousesOrders = app(RealtimePendingOrdersService::class)->warehousesOrders();
         $warehousesOrders = app(RealtimePendingOrdersService::class)->warehousesOrders();
-        return view('control.panel', compact('owners','menus', 'warehousesOrders'));
+        return view('control.panel', compact('owners', 'menus', 'warehousesOrders'));
     }
     }
 
 
     public function orderCountingRecordsApi(Request $request)
     public function orderCountingRecordsApi(Request $request)
@@ -49,8 +49,8 @@ class ControlPanelController extends Controller
         $orderCountingRecordService = app(NewOrderCountingRecordService::class);
         $orderCountingRecordService = app(NewOrderCountingRecordService::class);
         $start = Carbon::parse($request->start)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->start;
         $start = Carbon::parse($request->start)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->start;
         $end = Carbon::parse($request->end)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->end;
         $end = Carbon::parse($request->end)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->end;
-        $ownerIds=$request->owner_ids;
-        if (!$ownerIds || in_array('all',$ownerIds)) $ownerIds = $this->getCountingOwnerIds(null);
+        $ownerIds = $request->owner_ids;
+        if (!$ownerIds || in_array('all', $ownerIds)) $ownerIds = $this->getCountingOwnerIds(null);
         $orderCountingRecords = $orderCountingRecordService->getOrderCountingRecordsApi($start, $end, $request->unit, $ownerIds);
         $orderCountingRecords = $orderCountingRecordService->getOrderCountingRecordsApi($start, $end, $request->unit, $ownerIds);
         return compact('orderCountingRecords');
         return compact('orderCountingRecords');
     }
     }
@@ -63,8 +63,8 @@ class ControlPanelController extends Controller
         $orderCountingRecordService = app(NewOrderCountingRecordService::class);
         $orderCountingRecordService = app(NewOrderCountingRecordService::class);
         $start = Carbon::parse($request->start)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->start;
         $start = Carbon::parse($request->start)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->start;
         $end = Carbon::parse($request->end)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->end;
         $end = Carbon::parse($request->end)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->end;
-        $ownerIds=$request->input('owner_ids');
-        if (!$ownerIds || in_array('all',$ownerIds)) $ownerIds = $this->getCountingOwnerIds(null);
+        $ownerIds = $request->input('owner_ids');
+        if (!$ownerIds || in_array('all', $ownerIds)) $ownerIds = $this->getCountingOwnerIds(null);
         $logisticsCountingRecords = $orderCountingRecordService->getLogisticRecordsApi($start, $end, $ownerIds);
         $logisticsCountingRecords = $orderCountingRecordService->getLogisticRecordsApi($start, $end, $ownerIds);
         return compact('logisticsCountingRecords');
         return compact('logisticsCountingRecords');
     }
     }
@@ -112,12 +112,8 @@ class ControlPanelController extends Controller
         if (!$ownerIds) {
         if (!$ownerIds) {
             return $permittingOwnerIds;
             return $permittingOwnerIds;
         }
         }
-        return Cache::remember(
-            'PermittingOwnerIds' . '_' . auth()->user()->id . '_' . implode('_', $ownerIds),
-            600, function () use ($ownerIds, $permittingOwnerIds) {
-            /** @var User $user */
-            return array_intersect($ownerIds, $permittingOwnerIds);
-        });
+        //去掉缓存
+        return array_intersect($ownerIds, $permittingOwnerIds);
     }
     }
 
 
     /**
     /**
@@ -127,12 +123,12 @@ class ControlPanelController extends Controller
     {
     {
         //转化为Carbon
         //转化为Carbon
         $start = Carbon::parse(request("start"));
         $start = Carbon::parse(request("start"));
-        $end   = Carbon::parse(request("end"));
+        $end = Carbon::parse(request("end"));
 
 
         //定义三个数组 空间换时间 避免结果集二次转换
         //定义三个数组 空间换时间 避免结果集二次转换
         $title = []; //标题
         $title = []; //标题
         $data = []; //核心数据,二维数组
         $data = []; //核心数据,二维数组
-        foreach (CarbonPeriod::create($start,$end) as $date){
+        foreach (CarbonPeriod::create($start, $end) as $date) {
             /** @var $date Carbon */
             /** @var $date Carbon */
             $str = $date->format("Y-m-d");
             $str = $date->format("Y-m-d");
             $data[] = $this->getTargetData($str);
             $data[] = $this->getTargetData($str);
@@ -140,26 +136,26 @@ class ControlPanelController extends Controller
         }
         }
 
 
         //大于31天转换为月份显示
         //大于31天转换为月份显示
-        if ($end->diffInDays($start) > 31){
+        if ($end->diffInDays($start) > 31) {
             $title = [];
             $title = [];
             $sign = []; //标记是否已被插入
             $sign = []; //标记是否已被插入
             $dataTemp = []; //临时存储
             $dataTemp = []; //临时存储
 
 
-            foreach ($data as $datum){
-                $month = substr($datum["date"],0,7);
-                if (!isset($sign[$month])){
-                    $dataTemp[] = ["date"=>$month,"total"=>$datum["total"],"count"=>$datum["count"],"value"=>$datum["value"]];
+            foreach ($data as $datum) {
+                $month = substr($datum["date"], 0, 7);
+                if (!isset($sign[$month])) {
+                    $dataTemp[] = ["date" => $month, "total" => $datum["total"], "count" => $datum["count"], "value" => $datum["value"]];
                     $title[] = $month;
                     $title[] = $month;
-                    $sign[$month] = count($dataTemp)-1;
-                }else{
+                    $sign[$month] = count($dataTemp) - 1;
+                } else {
                     $dataTemp[$sign[$month]]["total"] += $datum["total"];
                     $dataTemp[$sign[$month]]["total"] += $datum["total"];
                     $dataTemp[$sign[$month]]["count"] += $datum["count"];
                     $dataTemp[$sign[$month]]["count"] += $datum["count"];
-                    $dataTemp[$sign[$month]]["value"] = (string)($dataTemp[$sign[$month]]["total"] ? intval(($dataTemp[$sign[$month]]["count"]/$dataTemp[$sign[$month]]["total"])*100) : 0);
+                    $dataTemp[$sign[$month]]["value"] = (string)($dataTemp[$sign[$month]]["total"] ? intval(($dataTemp[$sign[$month]]["count"] / $dataTemp[$sign[$month]]["total"]) * 100) : 0);
                 }
                 }
             }
             }
             $data = $dataTemp;
             $data = $dataTemp;
         }
         }
-        $this->success(["title"=>$title,"data"=>$data]);
+        $this->success(["title" => $title, "data" => $data]);
     }
     }
 
 
 
 
@@ -177,23 +173,23 @@ class ControlPanelController extends Controller
             $total = $orderPackageReceivedSyncRecord->succeed_count + $orderPackageReceivedSyncRecord->failed_count;
             $total = $orderPackageReceivedSyncRecord->succeed_count + $orderPackageReceivedSyncRecord->failed_count;
             $data[] = [
             $data[] = [
                 'date' => $orderPackageReceivedSyncRecord->recorded_at,
                 'date' => $orderPackageReceivedSyncRecord->recorded_at,
-                'total'=> $total,
-                'count'=>$orderPackageReceivedSyncRecord->succeed_count,
-                'value' => (int)($orderPackageReceivedSyncRecord->succeed_count / $total*100),
-                'logistic_name' =>$orderPackageReceivedSyncRecord->logistic_name
+                'total' => $total,
+                'count' => $orderPackageReceivedSyncRecord->succeed_count,
+                'value' => (int)($orderPackageReceivedSyncRecord->succeed_count / $total * 100),
+                'logistic_name' => $orderPackageReceivedSyncRecord->logistic_name
             ];
             ];
         }
         }
         $title = [];
         $title = [];
         foreach ($data as $data_item) {
         foreach ($data as $data_item) {
             $title[] = $data_item['date'];
             $title[] = $data_item['date'];
         }
         }
-        return ['success' =>true, 'data' =>['data'=>$data,'title'=>$title]];
+        return ['success' => true, 'data' => ['data' => $data, 'title' => $title]];
     }
     }
 
 
     public function exceptionTypeApi(Request $request)
     public function exceptionTypeApi(Request $request)
     {
     {
-        $ownerIds=$request->owner_ids;
-        if (!$ownerIds || in_array('all',$ownerIds)) $ownerIds = $this->getCountingOwnerIds(null);
+        $ownerIds = $request->owner_ids;
+        if (!$ownerIds || in_array('all', $ownerIds)) $ownerIds = $this->getCountingOwnerIds(null);
         $service = app('OrderPackageExceptionTypeCountingRecordService');
         $service = app('OrderPackageExceptionTypeCountingRecordService');
 
 
         $data = $service->get([
         $data = $service->get([
@@ -201,7 +197,7 @@ class ControlPanelController extends Controller
             'end_date' => $request->end,
             'end_date' => $request->end,
             'owner_ids' => $ownerIds,
             'owner_ids' => $ownerIds,
         ]);
         ]);
-        $this->success(["title"=>'',"data"=>$data]);
+        $this->success(["title" => '', "data" => $data]);
     }
     }
 
 
     /**
     /**
@@ -212,7 +208,7 @@ class ControlPanelController extends Controller
      */
      */
     private function getTargetData(string $date)
     private function getTargetData(string $date)
     {
     {
-        if ($date == date("Y-m-d")){
+        if ($date == date("Y-m-d")) {
             $sql = <<<sql
             $sql = <<<sql
 SELECT DATE_FORMAT(order_packages.created_at,'%Y-%m-%d') date,
 SELECT DATE_FORMAT(order_packages.created_at,'%Y-%m-%d') date,
 SUM(CASE WHEN order_packages.weighed_at IS NOT NULL THEN 1 ELSE 0 END) AS count,
 SUM(CASE WHEN order_packages.weighed_at IS NOT NULL THEN 1 ELSE 0 END) AS count,
@@ -221,13 +217,13 @@ AND order_packages.created_at >= '{$date} 00:00:00' GROUP BY date
 sql;
 sql;
 
 
             $pack = DB::selectOne(DB::raw($sql));
             $pack = DB::selectOne(DB::raw($sql));
-            if (!$pack)return ["date"=>$date,"total"=>0,"count"=>0,"value"=>0];
-            return ["date"=>$pack->date,"total"=>$pack->total,"count"=>$pack->count,"value"=>(string)($pack->total ? intval(($pack->count/$pack->total)*100) : 0)];
+            if (!$pack) return ["date" => $date, "total" => 0, "count" => 0, "value" => 0];
+            return ["date" => $pack->date, "total" => $pack->total, "count" => $pack->count, "value" => (string)($pack->total ? intval(($pack->count / $pack->total) * 100) : 0)];
         }
         }
-        return app(CacheService::class)->getOrExecute("weight.".$date,function ()use($date){
-            $count = OrderPackageCountingRecord::query()->where("targeted_at",$date)->first();
-            if (!$count)return ["date"=>$date,"total"=>0,"count"=>0,"value"=>0];
-            return ["date"=>$count->targeted_at,"total"=>$count->total_count,"count"=>$count->un_weigh_count,"value"=>(string)($count->total_count ? intval(($count->un_weigh_count/$count->total_count)*100) : 0)];
-        },config("cache.expirations.forever"));
+        return app(CacheService::class)->getOrExecute("weight." . $date, function () use ($date) {
+            $count = OrderPackageCountingRecord::query()->where("targeted_at", $date)->first();
+            if (!$count) return ["date" => $date, "total" => 0, "count" => 0, "value" => 0];
+            return ["date" => $count->targeted_at, "total" => $count->total_count, "count" => $count->un_weigh_count, "value" => (string)($count->total_count ? intval(($count->un_weigh_count / $count->total_count) * 100) : 0)];
+        }, config("cache.expirations.forever"));
     }
     }
 }
 }

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

@@ -0,0 +1,84 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\AsyncResponse;
+use App\OracleDOCASNHeader;
+use App\Services\HandInStorageService;
+use Illuminate\Http\Request;
+
+class HandInStorageController extends Controller
+{
+    use AsyncResponse;
+    /**
+     * 搜索查詢asn
+     */
+    public function selectAsn(Request $request)
+    {
+        /** @var HandInStorageService $handInStorageService  */
+        $handInStorageService=app('HandInStorageService');
+        $asnno= $request->input('asnno');
+        $asns =$handInStorageService->selectAsn($asnno);
+        if ($asns->count()>0){
+            $this->success($asns);
+        }else{
+            $this->error('未搜索到ASN单');
+        }
+    }
+    /**
+     * @param $asnno
+     * 跳转到收货明细页面
+     */
+    public function receiveDetailPage($asnno,$customerid)
+    {
+        /** @var HandInStorageService $handInStorageService  */
+        $handInStorageService=app('HandInStorageService');
+        if (!$customerid||$customerid=='undefined')
+            $customerid=OracleDOCASNHeader::query()->where('asnno',$asnno)->value('customerid');
+        $qualityStatus=$handInStorageService->getQualityStatus();
+        $attributeLocations=$handInStorageService->getAttributeLocation();
+        return view('store.handInStorage.receiveDetailPage')
+            ->with(['asnno'=>$asnno,'customerid'=>$customerid,'qualityStatus'=>$qualityStatus,'attributeLocations'=>$attributeLocations]);
+    }
+
+    /**
+     * @param Request $request
+     * 查询富勒asn_detail(集合)
+     */
+    public function selectAsnDetails(Request $request)
+    {
+        $asnno= $request->input('asnno');
+        $asnDetails =app('HandInStorageService')->selectAsnDetails($asnno);
+        if ($asnDetails->count()>0)$this->success($asnDetails);
+        else $this->error('未搜索到ASN详情单');
+
+    }
+    /**
+     * @param Request $request
+     * 查询富勒bas_sku 并关联 bas_lotid
+     */
+    public function getBasSkuWithLot(Request $request): array
+    {
+        $customerid= $request->input('customerid');
+        $sku= $request->input('sku');
+        $asnno= $request->input('asnno');
+        $asnDetail=app('HandInStorageService')->getAsnDetail($asnno,$sku);
+        $basSku =app('HandInStorageService')->getBasSkuLotId($customerid,$sku);
+        if (isset($basSku)&&isset($asnDetail))return ['success'=>true,'basSku'=>$basSku,'asnDetail'=>$asnDetail];
+        else $this->error('无效条码');
+    }
+
+    public function fluxHandIn(Request $request)
+    {
+        $info=$request->input('info');
+//        dd($info);
+        if (!$info['customerid']||!$info['sku']||!$info['asnno']) $this->error('参数错误');
+        if ($info['amount']+$info['receivedqty']>$info['expectedqty'])$this->error('收货数大于预期数');
+        /** @var HandInStorageService $handInStorageService  */
+        $handInStorageService=app('HandInStorageService');
+        $handInStorageService->fluxHandIn($info);
+//        dd($result,"111");
+    }
+
+
+}

+ 8 - 0
app/Http/Controllers/HomeController.php

@@ -34,4 +34,12 @@ class HomeController extends Controller
     {
     {
         return view('home');
         return view('home');
     }
     }
+
+    public function help()
+    {
+        $filePath = base_path('文档/SystemHandBook.md');
+        $read = @file_get_contents($filePath);
+        $read = str_replace(["\r","\n",'"'],["\\r",'\\n',"'"],$read);
+        return view("help",compact("read"));
+    }
 }
 }

+ 12 - 34
app/Http/Controllers/LogisticController.php

@@ -7,8 +7,10 @@ use Exception;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Validator;
 use Illuminate\Support\Facades\Validator;
+use Illuminate\Support\Str;
 
 
 class LogisticController extends Controller
 class LogisticController extends Controller
 {
 {
@@ -24,23 +26,13 @@ class LogisticController extends Controller
         return view('maintenance.logistic.index',['logistics'=>$logistics]);
         return view('maintenance.logistic.index',['logistics'=>$logistics]);
     }
     }
 
 
-    /**
-     * Show the form for creating a new resource.
-     *
-     * @return Response
-     */
     public function create()
     public function create()
     {
     {
         if(!Gate::allows('承运商-录入')){ return view("exception.authority");  }
         if(!Gate::allows('承运商-录入')){ return view("exception.authority");  }
         return view('maintenance.logistic.create');
         return view('maintenance.logistic.create');
     }
     }
 
 
-    /**
-     * Store a newly created resource in storage.
-     *
-     * @param Request $request
-     * @return Response
-     */
+
     public function store(Request $request)
     public function store(Request $request)
     {
     {
         if(!Gate::allows('承运商-录入')){ return view("exception.authority");  }
         if(!Gate::allows('承运商-录入')){ return view("exception.authority");  }
@@ -70,26 +62,19 @@ class LogisticController extends Controller
             'delivery_fee' => ['nullable', 'numeric', 'min:0'],
             'delivery_fee' => ['nullable', 'numeric', 'min:0'],
         ]);
         ]);
     }
     }
-    /**
-     * Display the specified resource.
-     *
-     * @param Logistic $logistic
-     * @return Response
-     */
-    public function show(Logistic $logistic)
-    {
-        //
-    }
 
 
-    /**
-     * Show the form for editing the specified resource.
-     *
-     * @param Logistic $logistic
-     * @return Response
-     */
     public function edit(Logistic $logistic)
     public function edit(Logistic $logistic)
     {
     {
         if(!Gate::allows('承运商-编辑')){ return view("exception.authority");  }
         if(!Gate::allows('承运商-编辑')){ return view("exception.authority");  }
+        $logistic = $logistic->toArray();
+        if ($logistic["tag"]){
+            $tag = explode(",",$logistic["tag"]);
+            $map = array_flip(Logistic::TAGS);
+            foreach ($tag as &$t)$t = $map[$t];
+            $logistic["tag"] = implode(",",$tag);
+        }
+        $key = 'LogisticAll_'.implode("",["id","name","tag"]).Str::studly("物流");
+        Cache::pull($key);
         return view('maintenance.logistic.edit',['logistic'=>$logistic]);
         return view('maintenance.logistic.edit',['logistic'=>$logistic]);
     }
     }
 
 
@@ -104,13 +89,6 @@ class LogisticController extends Controller
         return redirect('maintenance/logistic/')->with('successTip',"成功修改承运商“{$logistic['name']}”!");
         return redirect('maintenance/logistic/')->with('successTip',"成功修改承运商“{$logistic['name']}”!");
     }
     }
 
 
-    /**
-     * Remove the specified resource from storage.
-     *
-     * @param Logistic $logistic
-     * @return array|Response
-     * @throws Exception
-     */
     public function destroy(Logistic $logistic)
     public function destroy(Logistic $logistic)
     {
     {
         if(!Gate::allows('承运商-删除')){ return view("exception.authority");  }
         if(!Gate::allows('承运商-删除')){ return view("exception.authority");  }

+ 66 - 0
app/Http/Controllers/MaterialBoxModelController.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\AsyncResponse;
+use App\MaterialBoxModel;
+use App\Owner;
+use Illuminate\Support\Facades\Validator;
+
+class MaterialBoxModelController extends Controller
+{
+    use AsyncResponse;
+    public function index()
+    {
+        $models = MaterialBoxModel::query()->get();
+        return view("maintenance.materialBoxModel.index",compact("models"));
+    }
+
+    public function save()
+    {
+        $id = request("id");
+        $errors = Validator::make(request()->input(), [
+            'code'=>['required',$id?"unique:material_box_models,code,$id":"unique:material_box_models,code"],
+            'maximum_kind'=>['required',"integer","min:1"],
+            'description'=>['nullable'],
+        ],[
+            'integer'=>':attribute 非法参数',
+            'required'=>':attribute 必填',
+            'unique'=>':attribute 已存在',
+        ],[
+            'code'=>'编码',
+            'maximum_kind'=>'最大商品种类',
+            'description'=>'说明',
+        ]);
+        if ($errors->errors()->count())$this->success(["errors"=>$errors->errors()]);
+        if (!$id) $this->success(MaterialBoxModel::query()->create([
+                'code' => request("code"),
+                'maximum_kind' => request("maximum_kind"),
+                'description' => request("description"),
+            ]));
+        $model = MaterialBoxModel::query()->find($id);
+        if (!$model)$this->error("模型不存在");
+        $model->update(request()->only(["code",'maximum_kind',"description"]));
+        $this->success($model);
+    }
+
+    public function destroy()
+    {
+        $this->success(MaterialBoxModel::destroy(request("id")));
+    }
+
+    public function ownerSequence()
+    {
+        $owners = app("OwnerService")->getIntersectPermitting(["id","name","model_sequence"]);
+        $models = MaterialBoxModel::query()->get();
+        return view("maintenance.materialBoxModel.modelSequence",compact("owners","models"));
+    }
+
+    public function updateModelSequence()
+    {
+        $sequence = request("sequence");
+        $this->success(Owner::query()->where("id",request("id"))->update([
+            "model_sequence" => $sequence ?: null
+        ]));
+    }
+}

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

@@ -42,7 +42,7 @@ class MenuController extends Controller
         if (request()->has("font_style"))$update["font_style"] = request("font_style");
         if (request()->has("font_style"))$update["font_style"] = request("font_style");
         if (request()->has("route"))$update["route"] = request("route");
         if (request()->has("route"))$update["route"] = request("route");
         if (request()->has("diff")){
         if (request()->has("diff")){
-            $diff = request("diff"); //TODO 此处需要查询出模型 ->get()->each()来进行update操作以确保观察者检测到 下面同理
+            $diff = request("diff"); //此处需要查询出模型 ->get()->each()来进行update操作以确保观察者检测到 下面同理
             Menu::query()->whereIn("id",request("child"))->get()->each(function ($menu)use($diff){
             Menu::query()->whereIn("id",request("child"))->get()->each(function ($menu)use($diff){
                $menu->update(["level"=>DB::raw("level - {$diff}")]);
                $menu->update(["level"=>DB::raw("level - {$diff}")]);
             });
             });

+ 153 - 0
app/Http/Controllers/OwnerFeeTotalController.php

@@ -0,0 +1,153 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerDischargeTaskSettlementBillService;
+use App\Services\OwnerFeeTotalService;
+use App\Services\OwnerLogisticFeeReportService;
+use App\Services\OwnerProcessSettlementBillService;
+use App\Services\OwnerProcurementSettlementBillService;
+use App\Services\OwnerStoreFeeReportService;
+use App\Services\OwnerStoreOutFeeReportService;
+use App\Services\OwnerSundryFeeDetailService;
+use App\Services\OwnerWaybillSettlementBillService;
+use App\Services\SettlementBillsAreaFeeService;
+use App\Services\SettlementIndemnityFeeService;
+use Illuminate\Http\Request;
+
+class OwnerFeeTotalController extends Controller implements \App\Interfaces\SettlementBillControllerInterface
+{
+    use \App\Traits\SettlementBillTrait;
+
+    /** @var OwnerFeeTotalService $service */
+    private $service;
+
+    /** @var OwnerBillReportArchiveService $archiveService */
+    private $archiveService;
+
+
+    /**
+     * OwnerDischargeTaskSettlementBillController constructor.
+     */
+    public function __construct()
+    {
+        $this->service = app('OwnerFeeTotalService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $feeTotal = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'paginateParams' => $paginateParams,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        $isArchivedItems = collect([
+            'expressFee' => $this->archiveService->isArchived($counting_month, $owner_id, '快递费-合计'),
+            'logisticFee' => $this->archiveService->isArchived($counting_month, $owner_id, '物流费'),
+            'packingMaterialFee' => $this->archiveService->isArchived($counting_month, $owner_id, '包材费'),
+            'processFee' => $this->archiveService->isArchived($counting_month, $owner_id, '加工费'),
+            'storageFee' => $this->archiveService->isArchived($counting_month, $owner_id, '仓储费'),
+            'storeFee' => $this->archiveService->isArchived($counting_month, $owner_id, '入库费-合计'),
+            'storeOutFee' => $this->archiveService->isArchived($counting_month, $owner_id, '出库费-合计'),
+            'sundryFee' => $this->archiveService->isArchived($counting_month, $owner_id, '杂项费'),
+            'unloadFee' => $this->archiveService->isArchived($counting_month, $owner_id, '卸货费'),
+            'indemnityFee' => $this->archiveService->isArchived($counting_month, $owner_id, '理赔费'),
+        ]);
+        return view('finance.settlementBills.totalFee.index', compact('feeTotal', 'paginateParams', 'owners', 'owner', 'request', 'isArchived', 'isArchivedItems'));
+    }
+
+
+    public function export(Request $request)
+    {
+        // TODO: Implement export() method.
+    }
+
+    public function confirmBill(Request $request): \Illuminate\Http\RedirectResponse
+    {
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $billReport = OwnerBillReport::query()
+            ->select('id')
+            ->where('owner_id', $owner_id)
+            ->where('counting_month', $counting_month)
+            ->firstOr(function () {
+                return new OwnerBillReport();
+            });
+        OwnerBillReportArchive::query()->create([
+            'owner_bill_report_id' => $billReport->id ?? null,
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this->service::TYPE,
+            'archiver_id' => auth()->id(),
+            'archived_at' => now(),
+            'information' => [],
+        ]);
+
+        $unArchived = $this->archiveService->getUnAchieved($counting_month, $owner_id);
+        foreach ($unArchived as $type) {
+            switch ($type) {
+                case '仓储费':
+                    /**@var $storageFeeService  SettlementBillsAreaFeeService */
+                    $storageFeeService = app('SettlementBillsAreaFeeService');
+                    $storageFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '快递费-合计':
+                    /**@var $expressFeeService  OwnerLogisticFeeReportService */
+                    $expressFeeService = app('OwnerLogisticFeeReportService');
+                    $expressFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '入库费-合计':
+                    /**@var $storeFeeService  OwnerStoreFeeReportService */
+                    $storeFeeService = app('OwnerStoreFeeReportService');
+                    $storeFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '出库费-合计':
+                    /**@var $storeOutFeeService  OwnerStoreOutFeeReportService */
+                    $storeOutFeeService = app('OwnerStoreOutFeeReportService');
+                    $storeOutFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '物流费':
+                    /**@var $logisticFeeService  OwnerWaybillSettlementBillService */
+                    $logisticFeeService = app('OwnerWaybillSettlementBillService');
+                    $logisticFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '包材费':
+                    /**@var $packingMaterialFeeService  OwnerProcurementSettlementBillService */
+                    $packingMaterialFeeService = app('OwnerProcurementSettlementBillService');
+                    $packingMaterialFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '加工费':
+                    /**@var $processFeeService  OwnerProcessSettlementBillService */
+                    $processFeeService = app('OwnerProcessSettlementBillService');
+                    $processFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '杂项费':
+                    /**@var $sundryFeeService  OwnerSundryFeeDetailService */
+                    $sundryFeeService = app('OwnerSundryFeeDetailService');
+                    $sundryFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '卸货费':
+                    /**@var $unloadFeeService  OwnerDischargeTaskSettlementBillService */
+                    $unloadFeeService = app('OwnerDischargeTaskSettlementBillService');
+                    $unloadFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+                case '理赔费':
+                    /**@var $indemnityFeeService  SettlementIndemnityFeeService */
+                    $indemnityFeeService = app('SettlementIndemnityFeeService');
+                    $indemnityFeeService->confirmBill($counting_month, $owner_id);
+                    break;
+            }
+        }
+        return back()->with('success', '确认成功');
+    }
+}

+ 0 - 108
app/Http/Controllers/OwnerLogisticFeeDetailController.php

@@ -1,108 +0,0 @@
-<?php
-
-namespace App\Http\Controllers;
-
-use App\Owner;
-use App\OwnerBillReport;
-use App\OwnerBillReportArchive;
-use App\Services\OwnerBillReportArchiveService;
-use App\Services\OwnerLogisticFeeDetailService;
-use Carbon\Carbon;
-use Illuminate\Http\RedirectResponse;
-use Illuminate\Http\Request;
-use Oursdreams\Export\Export;
-
-class OwnerLogisticFeeDetailController extends Controller
-{
-    /** @var $service OwnerLogisticFeeDetailService */
-    private $service;
-
-    /** @var  $archiveService OwnerBillReportArchiveService */
-    private $archiveService;
-
-    /**
-     * Display a listing of the resource.
-     *
-     */
-    public function index(Request $request)
-    {
-        $paginateParams = $request->input();
-        list($permittingOwnerIds, $owner_id, $start, $end) = $this->getRequestParams($request->owner_id, $request->year, $request->month);
-        $details = $this->service->getDetails($owner_id, $start, $end, $paginateParams);
-        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
-        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
-        $this->archiveService = app('OwnerBillReportArchiveService');
-        $isArchived =  $this->archiveService->isArchived($start, $owner_id, OwnerBillReportArchive::$enums['type']['快递费-明细']);
-        $request = collect($request->all());
-        return view('finance.settlementBills.logisticFee.detail.index', compact('details', 'paginateParams', 'owners', 'owner', 'request','isArchived'));
-    }
-
-    public function export(Request $request)
-    {
-        list($permittingOwnerIds, $owner_id, $start, $end) = $this->getRequestParams($request->owner_id, $request->year, $request->month);
-        $query = $this->service->getSql($owner_id, $start, $end);
-        if (!$request->exists('checkAllSign')) {
-            $query->whereIn('id', explode(',', $request['data']));
-        }
-        $details = $this->service->buildDetails($query->get());
-        $json = [];
-        foreach ($details as $detail) {
-            $json[] = array_values($detail);
-        }
-        $row = ['主键', '快递公司', '省份', '快递单号', '重量', '首重价格', '续重价格', '快递费',];
-        return Export::make($row, $json, "快递费用详情");
-    }
-
-    /**
-     * @param $owner_id
-     * @param $year
-     * @param $month
-     * @return array
-     */
-    private function getRequestParams($owner_id, $year, $month): array
-    {
-        $this->service = app('OwnerLogisticFeeDetailService');
-        $this->userService = app('UserService');
-        $permittingOwnerIds = $this->userService->getPermittingOwnerIds(auth()->user());
-        if (is_null($owner_id)) {
-            $owner_id = $permittingOwnerIds[0];
-        }
-        if (is_null($year)) {
-            $year = now()->subMonth()->year;
-        }
-        if (is_null($month)) {
-            $month = now()->subMonth()->month;
-        }
-        $day = Carbon::parse($year . '-' . $month . '-01');
-        return array($permittingOwnerIds, $owner_id, $day->startOfMonth()->toDateString(), $day->endOfMonth()->toDateString());
-    }
-
-    /**
-     * 确认账单
-     * @param Request $request
-     * @return RedirectResponse
-     */
-    public function confirmBill(Request $request)
-    {
-        $this->service = app('OwnerLogisticFeeDetailService');
-        $this->archiveService = app('OwnerBillReportArchiveService');
-        list($permittingOwnerIds, $owner_id, $start, $end) = $this->getRequestParams($request->owner_id, $request->year, $request->month);
-        $billReport = OwnerBillReport::query()
-            ->select('storage_fee', 'id')
-            ->where('owner_id', $owner_id)
-            ->where('counting_month', $start)
-            ->firstOr(function () {
-                return new OwnerBillReport();
-            });
-        OwnerBillReportArchive::query()->create([
-            'owner_bill_report_id' => $billReport->id ?? null,
-            'owner_id' => $owner_id,
-            'counting_mouth' => $start,
-            'type' => $this->service::TYPE,
-            'archiver_id' => auth()->id(),
-            'archived_at' => now(),
-            'information' => [],
-        ]);
-        return back()->with('success', '确认成功');
-    }
-}

+ 17 - 0
app/Http/Controllers/OwnerSundryFeeDetailsController.php

@@ -4,15 +4,32 @@ namespace App\Http\Controllers;
 
 
 use App\Filters\OwnerSundryFeeDetailFilters;
 use App\Filters\OwnerSundryFeeDetailFilters;
 use App\Owner;
 use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
 use App\OwnerSundryFeeDetail;
 use App\OwnerSundryFeeDetail;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerSundryFeeDetailService;
+use App\Traits\SettlementBillTrait;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use App\Http\Requests\OwnerSundryFeeDetailRequest;
 use App\Http\Requests\OwnerSundryFeeDetailRequest;
 use Oursdreams\Export\Export;
 use Oursdreams\Export\Export;
 
 
 class OwnerSundryFeeDetailsController extends Controller
 class OwnerSundryFeeDetailsController extends Controller
 {
 {
+    use SettlementBillTrait;
+
+
+
+    /** @var OwnerBillReportArchiveService $archiveService */
+    private $archiveService;
+
+    /** @var OwnerSundryFeeDetailService $service */
+    private $service;
+
     public function __construct()
     public function __construct()
     {
     {
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $this->service = app('OwnerSundryFeeDetailService');
         $this->middleware('auth');
         $this->middleware('auth');
     }
     }
 
 

+ 85 - 0
app/Http/Controllers/OwnerWayBillFeeDetailController.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\OwnerWayBillFeeDetail;
+use Illuminate\Http\Request;
+
+class OwnerWayBillFeeDetailController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\OwnerWayBillFeeDetail  $ownerWayBillFeeDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function show(OwnerWayBillFeeDetail $ownerWayBillFeeDetail)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\OwnerWayBillFeeDetail  $ownerWayBillFeeDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(OwnerWayBillFeeDetail $ownerWayBillFeeDetail)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\OwnerWayBillFeeDetail  $ownerWayBillFeeDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, OwnerWayBillFeeDetail $ownerWayBillFeeDetail)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\OwnerWayBillFeeDetail  $ownerWayBillFeeDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(OwnerWayBillFeeDetail $ownerWayBillFeeDetail)
+    {
+        //
+    }
+}

+ 24 - 0
app/Http/Controllers/OwnerWaybillSettlementBillController.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+
+class OwnerWaybillSettlementBillController extends Controller implements \App\Interfaces\SettlementBillControllerInterface
+{
+    //
+    public function index(Request $request)
+    {
+        // TODO: Implement index() method.
+    }
+
+    public function confirmBill(Request $request): \Illuminate\Http\RedirectResponse
+    {
+        // TODO: Implement confirmBill() method.
+    }
+
+    public function export(Request $request)
+    {
+        // TODO: Implement export() method.
+    }
+}

+ 100 - 0
app/Http/Controllers/RequirementController.php

@@ -0,0 +1,100 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Filters\RequirementFilters;
+use App\Http\Requests\RequirementRequest;
+use App\Requirement;
+use App\Role;
+use Illuminate\Http\Request;
+use Illuminate\Http\Response;
+use Illuminate\Support\Facades\Auth;
+
+class RequirementController extends Controller
+{
+
+    public function index(Request $request, RequirementFilters $filters)
+    {
+        $requirements = Requirement::query()->filter($filters)
+            ->with(['creator', 'workers'])
+            ->orderByDesc('created_at')
+            ->paginate($request->paginate ?? 50);
+        $canCreateRequirementUsers = Role::query()->where('name', '创建需求')->first()->users;
+
+        $canWorkRequirementUsers = Role::query()->where('name', '执行需求')->first()->users;
+        $paginateParams = $request->paginateParams;
+        return view('requirement.index', compact('canWorkRequirementUsers', 'canCreateRequirementUsers', 'requirements', 'paginateParams'));
+    }
+
+    public function create(Requirement $requirement)
+    {
+        return view('requirement.create_and_edit', compact('requirement'));
+    }
+
+    public function store(RequirementRequest $request, Requirement $requirement)
+    {
+        $requirement->fill($request->all());
+        $requirement->user_id = Auth::id();
+        $requirement->status = '已发布';
+        $requirement->save();
+        return redirect()->route('requirements.index', $requirement->id)->with('success', '需求创建成功!');
+    }
+
+
+    public function show(Requirement $requirement)
+    {
+        $requirement->loadMissing(['creator', 'workers']);
+        $creators = Role::query()->where('name', '创建需求')->first()->users;
+        $workers = Role::query()->where('name', '执行需求')->first()->users;
+        return view('requirement.show', compact('requirement', 'creators', 'workers'));
+    }
+
+
+    public function edit(Requirement $requirement)
+    {
+        $requirement->loadMissing(['creator', 'workers']);
+        $creators = Role::query()->where('name', '创建需求')->first()->users;
+        $workers = Role::query()->where('name', '执行需求')->first()->users;
+        return view('requirement.create_and_edit', compact('requirement', 'creators', 'workers'));
+    }
+
+
+    public function update(Request $request, Requirement $requirement)
+    {
+        $requirement->update($request->all());
+        return redirect()->route('requirements.show', $requirement->id)->with('success', '编辑成功');
+    }
+
+
+    public function destroy(Requirement $requirement)
+    {
+        $this->authorize('destroy', $requirement);
+        $requirement->delete();
+        return redirect()->route('requirements.index', $requirement->id)->with('success', '删除需求成功!');
+
+    }
+
+    public function begin(Requirement $requirement)
+    {
+        $this->authorize('begin', $requirement);
+        $requirement->status = '已开始';
+        $requirement->began_at = now();
+        $requirement->save();
+        return redirect()->route('requirements.show', $requirement->id)->with('success', '需求已开始执行');
+    }
+
+    public function finish(Request $request, Requirement $requirement)
+    {
+        $requirement->status = '已完成';
+        if (count($request->users) > 0) {
+            $attachData = [];
+            foreach ($request->users as $worker) {
+                $attachData[$worker['name']] = ['score' => $worker['score']];
+            }
+            $requirement->workers()->sync($attachData);
+        }
+        $requirement->finished_at = now();
+        $requirement->save();
+        return redirect()->route('requirements.show', $requirement->id)->with('success', '需求已完成');
+    }
+}

+ 85 - 0
app/Http/Controllers/RequirementUserController.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\RequirementUser;
+use Illuminate\Http\Request;
+
+class RequirementUserController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\RequirementUser  $requirementUser
+     * @return \Illuminate\Http\Response
+     */
+    public function show(RequirementUser $requirementUser)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\RequirementUser  $requirementUser
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(RequirementUser $requirementUser)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\RequirementUser  $requirementUser
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, RequirementUser $requirementUser)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\RequirementUser  $requirementUser
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(RequirementUser $requirementUser)
+    {
+        //
+    }
+}

+ 67 - 0
app/Http/Controllers/SettlementBillExpressFeeDetailController.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Interfaces\SettlementBillControllerInterface;
+use App\Owner;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerLogisticFeeDetailService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillExpressFeeDetailController extends Controller implements SettlementBillControllerInterface
+{
+    use  SettlementBillTrait;
+
+    /** @var $service OwnerLogisticFeeDetailService */
+    private $service;
+
+    /** @var  $archiveService OwnerBillReportArchiveService */
+    private $archiveService;
+
+    /**
+     * OwnerLogisticFeeDetailController constructor.
+     */
+    public function __construct()
+    {
+        $this->service = app('OwnerLogisticFeeDetailService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+    /**
+     * Display a listing of the resource.
+     *
+     */
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month,$request->owner_id);
+        $details = $this->service->get([
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'paginateParams' => $paginateParams,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.expressFee.detail.index', compact('details', 'paginateParams', 'owners', 'owner', 'request'));
+    }
+
+    public function export(Request $request)
+    {
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->owner_id, $request->year, $request->month);
+        $query = $this->service->getSql($owner_id, $counting_month);
+        if (!$request->exists('checkAllSign')) {
+            $query->whereIn('id', explode(',', $request['data']));
+        }
+        $details = $this->service->buildDetails($query->get());
+        $json = [];
+        foreach ($details as $detail) {
+            $json[] = array_values($detail);
+        }
+        $row = ['主键', '快递公司', '省份', '快递单号', '重量', '首重价格', '续重价格', '快递费',];
+        return Export::make($row, $json, "快递费用详情");
+    }
+}

+ 7 - 36
app/Http/Controllers/OwnerLogisticFeeReportController.php → app/Http/Controllers/SettlementBillExpressFeeReportController.php

@@ -8,13 +8,15 @@ use App\OwnerBillReportArchive;
 use App\Services\OwnerBillReportArchiveService;
 use App\Services\OwnerBillReportArchiveService;
 use App\Services\OwnerLogisticFeeReportService;
 use App\Services\OwnerLogisticFeeReportService;
 use App\Services\UserService;
 use App\Services\UserService;
+use App\Traits\SettlementBillTrait;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Illuminate\Pagination\LengthAwarePaginator;
 use Illuminate\Pagination\LengthAwarePaginator;
 use Oursdreams\Export\Export;
 use Oursdreams\Export\Export;
 
 
-class OwnerLogisticFeeReportController extends Controller
+class SettlementBillExpressFeeReportController extends Controller
 {
 {
+    use SettlementBillTrait;
     /* @var OwnerLogisticFeeReportService $service */
     /* @var OwnerLogisticFeeReportService $service */
     private $service;
     private $service;
     /* @var UserService $userService */
     /* @var UserService $userService */
@@ -23,13 +25,6 @@ class OwnerLogisticFeeReportController extends Controller
     /** @var  $archiveService OwnerBillReportArchiveService */
     /** @var  $archiveService OwnerBillReportArchiveService */
     private $archiveService;
     private $archiveService;
 
 
-    /**
-     * OwnerLogisticFeeReportController constructor.
-     */
-    public function __construct()
-    {
-        $this->middleware('auth');
-    }
 
 
 
 
     /**
     /**
@@ -55,11 +50,8 @@ class OwnerLogisticFeeReportController extends Controller
         $this->archiveService = app('OwnerBillReportArchiveService');
         $this->archiveService = app('OwnerBillReportArchiveService');
         $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, OwnerBillReportArchive::$enums['type']['快递费-合计']);
         $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, OwnerBillReportArchive::$enums['type']['快递费-合计']);
 
 
-        $request = $request->all();
-        $request['year'] = \Carbon\Carbon::parse($counting_month)->year;
-        $request['month'] = \Carbon\Carbon::parse($counting_month)->month;
-        $request = collect($request);
-        return view('finance.settlementBills.logisticFee.report.index', compact('reports', 'recordTotal', 'paginateParams', 'owners', 'owner', 'isArchived', 'request', 'reportPaginator'));
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.expressFee.report.index', compact('reports', 'recordTotal', 'paginateParams', 'owners', 'owner', 'isArchived', 'request', 'reportPaginator'));
     }
     }
 
 
     public function export(Request $request)
     public function export(Request $request)
@@ -126,32 +118,11 @@ class OwnerLogisticFeeReportController extends Controller
      * @param Request $request
      * @param Request $request
      * @return RedirectResponse
      * @return RedirectResponse
      */
      */
-    public function confirmBill(Request $request)
+    public function confirmBill(Request $request):RedirectResponse
     {
     {
         $this->service = app('OwnerLogisticFeeReportService');
         $this->service = app('OwnerLogisticFeeReportService');
-        $this->archiveService = app('OwnerBillReportArchiveService');
         list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
         list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
-        $billReport = OwnerBillReport::query()
-            ->select('storage_fee', 'id')
-            ->where('owner_id', $owner_id)
-            ->where('counting_month', $counting_month)
-            ->firstOr(function () {
-                return new OwnerBillReport();
-            });
-        $reports = $this->service->getRecords($owner_id, $counting_month);
-        $recordTotal = $this->service->getRecordTotal($owner_id, $counting_month);
-        OwnerBillReportArchive::query()->create([
-            'owner_bill_report_id' => $billReport->id ?? null,
-            'owner_id' => $owner_id,
-            'counting_mouth' => $counting_month,
-            'type' => $this->service::TYPE,
-            'archiver_id' => auth()->id(),
-            'archived_at' => now(),
-            'information' => [
-                'reports' => $reports,
-                'recordTotal' => $recordTotal,
-            ],
-        ]);
+        $this->service->confirmBill($counting_month, $owner_id);
         return back()->with('success', '确认成功');
         return back()->with('success', '确认成功');
     }
     }
 }
 }

+ 66 - 0
app/Http/Controllers/SettlementBillLogisticFeeController.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Interfaces\SettlementBillControllerInterface;
+use App\Owner;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerWaybillSettlementBillService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillLogisticFeeController extends Controller implements SettlementBillControllerInterface
+{
+    use SettlementBillTrait;
+
+    /**
+     * @var $service OwnerWaybillSettlementBillService
+     */
+    private $service;
+
+    /**
+     * @var $archiveService OwnerBillReportArchiveService
+     */
+    private $archiveService;
+    //
+
+    /**
+     * SettlementBillLogisticFeeController constructor.
+     */
+    public function __construct()
+    {
+        $this->service = app('OwnerWaybillSettlementBillService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $details = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'type' => $this->service::TYPE,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.logisticFee.index', compact('details', 'paginateParams', 'owners', 'owner', 'request', 'isArchived'));
+    }
+
+
+    public function export(Request $request)
+    {
+        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 = $query->get();
+        $json = $this->service->buildExport($details);
+        $row = ['承运商', '订单号', '收件人姓名', '收件人电话', '重量/体积', '计数单位', '计数区间', '省份', '市', '单价', '送货费', '提货费', '燃油附加费', '信息费', '其它费用', '备注', '起始计费', '起始计数', '运费合计'];
+        return Export::make($row, $json, "物流费");
+    }
+}

+ 66 - 0
app/Http/Controllers/SettlementBillPackingMaterialFeeController.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Interfaces\SettlementBillControllerInterface;
+use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerProcurementSettlementBillService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillPackingMaterialFeeController extends Controller implements SettlementBillControllerInterface
+{
+    use SettlementBillTrait;
+
+    /**php
+     * @var $archiveService OwnerBillReportArchiveService
+     */
+    private $archiveService;
+
+    /**
+     * @var $service OwnerProcurementSettlementBillService
+     */
+    private $service;
+
+    public function __construct()
+    {
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $this->service = app('OwnerProcurementSettlementBillService');
+    }
+
+    public function index(Request $request)
+    {
+
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        list($details, $total_fee) = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'type' => $this->service::TYPE,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.packingMaterialFee.index', compact('details', 'paginateParams', 'owners', 'owner', 'request', 'isArchived', 'total_fee'));
+    }
+
+
+    public function export(Request $request)
+    {
+        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 = $query->get();
+        $json = $this->service->buildExport($details);
+        $row = ['采购日期', '材料名称', '材料类型', '规格', '购买数量', '单价', '总计'];
+        return Export::make($row, $json, "包材费");
+    }
+}

+ 65 - 0
app/Http/Controllers/SettlementBillProcessFeeController.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Interfaces\SettlementBillControllerInterface;
+use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerProcessSettlementBillService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillProcessFeeController extends Controller implements SettlementBillControllerInterface
+{
+    use SettlementBillTrait;
+
+    /** @var $service OwnerProcessSettlementBillService */
+    private $service;
+
+    /** @var  $archiveService OwnerBillReportArchiveService */
+    private $archiveService;
+
+    /**
+     * OwnerProcessSettlementBillController constructor.
+     */
+    public function __construct()
+    {
+        $this->service = app('OwnerProcessSettlementBillService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        list($details, $totalFee) = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'paginateParams' => $paginateParams,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.processFee.index', compact('details', 'paginateParams', 'owners', 'owner', 'request', 'isArchived', 'totalFee'));
+    }
+
+    public function export(Request $request)
+    {
+        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 = $query->get();
+        $json = $this->service->buildExport($details);
+
+        $row = ['作业时间', '作业类型', '任务号', '单据号', '加工备注', '数量', '单价', '收费'];
+        return Export::make($row, $json, "加工费");
+    }
+}

+ 26 - 47
app/Http/Controllers/SettlementBillOwnerAreaFeeController.php → app/Http/Controllers/SettlementBillStorageFeeController.php

@@ -10,101 +10,80 @@ use Carbon\Carbon;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Oursdreams\Export\Export;
 use Oursdreams\Export\Export;
+use Tightenco\Collect\Support\Collection;
 
 
 /**
 /**
  * 结算管理-结算账单-仓储费
  * 结算管理-结算账单-仓储费
  * Class SettlementBillOwnerAreaFeeController
  * Class SettlementBillOwnerAreaFeeController
  * @package App\Http\Controllers
  * @package App\Http\Controllers
  */
  */
-class SettlementBillOwnerAreaFeeController extends Controller
+class SettlementBillStorageFeeController extends Controller implements \App\Interfaces\SettlementBillControllerInterface
 {
 {
+    use \App\Traits\SettlementBillTrait;
+
     /* @var $service SettlementBillsAreaFeeService */
     /* @var $service SettlementBillsAreaFeeService */
     private $service;
     private $service;
     /** @var  $archiveService OwnerBillReportArchiveService */
     /** @var  $archiveService OwnerBillReportArchiveService */
     private $archiveService;
     private $archiveService;
 
 
     /**
     /**
-     * SettlementBillOwnerAreaFeeController constructor.
+     * SettlementBillStorageFeeController constructor.
      */
      */
     public function __construct()
     public function __construct()
-    {
-        $this->middleware('auth');
-    }
-
-    public function index(Request $request)
     {
     {
         $this->service = app('SettlementBillsAreaFeeService');
         $this->service = app('SettlementBillsAreaFeeService');
         $this->archiveService = app('OwnerBillReportArchiveService');
         $this->archiveService = app('OwnerBillReportArchiveService');
-
-        list($permittingOwnerIds, $counting_month, $owner_id) = $this->service->getRequestParams($request->year, $request->month, $request->owner_id);
-        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, OwnerBillReportArchive::$enums['type']['仓储费']);
-        list($areaReports, $billReport, $price) = $this->service->get($owner_id, $counting_month);
-        $owners = Owner::query()->find($permittingOwnerIds);
-        $owner = Owner::query()->find($owner_id);
-        $request = $request->all();
-        $request['year'] = Carbon::parse($counting_month)->year;
-        $request['month'] = Carbon::parse($counting_month)->month;
-        $request = collect($request);
-        return view('finance.settlementBills.areaFee.index', compact('owner', 'owners', 'areaReports', 'billReport', 'price', 'request', 'isArchived'));
     }
     }
 
 
 
 
-    /**
-     * 确认账单
-     * @param Request $request
-     * @return RedirectResponse
-     */
-    public function confirmBill(Request $request)
+    public function index(Request $request)
     {
     {
-        $this->service = app('SettlementBillsAreaFeeService');
-        $this->archiveService = app('OwnerBillReportArchiveService');
-        list($permittingOwnerIds, $counting_month, $owner_id) = $this->service->getRequestParams($request->year, $request->month, $request->owner_id);
-        list($areaReports, $billReport, $price) = $this->service->get($owner_id, $counting_month);
-        OwnerBillReportArchive::query()->create([
-            'owner_bill_report_id' => $billReport->id ?? null,
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        list($areaReports, $billReport) = $this->service->get([
             'owner_id' => $owner_id,
             'owner_id' => $owner_id,
             'counting_month' => $counting_month,
             'counting_month' => $counting_month,
             'type' => $this->service::TYPE,
             'type' => $this->service::TYPE,
-            'archiver_id' => auth()->id(),
-            'archived_at' => now(),
-            'information' => [
-                'areaReports' => $areaReports,
-                'billReport' => $billReport,
-                'price' => $price,
-            ],
         ]);
         ]);
-        return back()->with('success', '确认成功');
+        $owners = Owner::query()->find($permittingOwnerIds);
+        $owner = Owner::query()->find($owner_id);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.storageFee.index', compact('owner', 'owners', 'areaReports', 'billReport', 'request', 'isArchived'));
     }
     }
 
 
     public function export(Request $request)
     public function export(Request $request)
     {
     {
-        $this->service = app('SettlementBillsAreaFeeService');
-        list($permittingOwnerIds, $counting_month, $owner_id) = $this->service->getRequestParams($request->year, $request->month, $request->owner_id);
-        list($areaReports, $billReport, $price) = $this->service->get($owner_id, $counting_month);
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        list($areaReports, $billReport) = $this->service->get([
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this->service::TYPE,
+        ]);
         $json = [];
         $json = [];
         foreach ($areaReports as $areaReport) {
         foreach ($areaReports as $areaReport) {
             $json[] = [
             $json[] = [
-                $areaReport['owner_storage_price_model']['using_type']??$areaReport['ownerStoragePriceModel']['using_type'],
+                $areaReport['owner_storage_price_model']['using_type'] ?? $areaReport['ownerStoragePriceModel']['using_type'],
                 '平面区',
                 '平面区',
                 $areaReport['area_on_flat'],
                 $areaReport['area_on_flat'],
                 $areaReport['accounting_area'],
                 $areaReport['accounting_area'],
-                $price,
+                $areaReport['owner_storage_price_model']['price'],
                 $billReport['storage_fee'],
                 $billReport['storage_fee'],
             ];
             ];
             $json[] = [
             $json[] = [
-                $areaReport['owner_storage_price_model']['using_type']??$areaReport['ownerStoragePriceModel']['using_type'],
+                $areaReport['owner_storage_price_model']['using_type'] ?? $areaReport['ownerStoragePriceModel']['using_type'],
                 '整托存储',
                 '整托存储',
                 $areaReport['area_on_tray'],
                 $areaReport['area_on_tray'],
                 $areaReport['accounting_area'],
                 $areaReport['accounting_area'],
-                $price,
+                $areaReport['owner_storage_price_model']['price'],
+
                 $billReport['storage_fee'],
                 $billReport['storage_fee'],
             ];
             ];
             $json[] = [
             $json[] = [
-                $areaReport['owner_storage_price_model']['using_type']??$areaReport['ownerStoragePriceModel']['using_type'],
+                $areaReport['owner_storage_price_model']['using_type'] ?? $areaReport['ownerStoragePriceModel']['using_type'],
                 '半托存储',
                 '半托存储',
                 $areaReport['area_on_half_tray'],
                 $areaReport['area_on_half_tray'],
                 $areaReport['accounting_area'],
                 $areaReport['accounting_area'],
-                $price,
+                $areaReport['owner_storage_price_model']['price'],
                 $billReport['storage_fee'],
                 $billReport['storage_fee'],
             ];
             ];
         }
         }

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

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Interfaces\SettlementBillControllerInterface;
+use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerStoreFeeDetailService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillStoreFeeDetailController extends Controller implements SettlementBillControllerInterface
+{
+    use SettlementBillTrait;
+
+    /** @var $service OwnerStoreFeeDetailService */
+    private $service;
+
+    /** @var  $archiveService OwnerBillReportArchiveService */
+    private $archiveService;
+
+    /**
+     * SettlementBillStoreFeeDetailController constructor.
+     */
+    public function __construct()
+    {
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $this->service = app('OwnerStoreFeeDetailService');
+    }
+
+    /**
+     * Display a listing of the resource.
+     *
+     */
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $details = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'type' => $this->service::TYPE,
+            'paginateParams' => $paginateParams,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.storeFee.detail.index', compact('details', 'paginateParams', 'owners', 'owner', 'request'));
+    }
+
+    public function export(Request $request)
+    {
+        $this->service = app('OwnerStoreFeeDetailService');
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $query = $this->service->getSql($counting_month, $owner_id);
+        if (!$request->exists('checkAllSign')) {
+            $query->whereIn('id', explode(',', $request['data']));
+        }
+        $details = $query->get();
+
+        $json = $this->service->buildExport($details);
+        $row = ['作业日期', '作业名称', '入库单号', '商品条码', '商品名称', '数量', '单价', '入库费'];
+        return Export::make($row, $json, "入库费明细");
+    }
+}

+ 93 - 0
app/Http/Controllers/SettlementBillStoreFeeReportController.php

@@ -0,0 +1,93 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerStoreFeeReportService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+use Tightenco\Collect\Support\Collection;
+
+class SettlementBillStoreFeeReportController extends Controller
+{
+    use SettlementBillTrait;
+
+    /* @var OwnerStoreFeeReportService $service */
+    private $service;
+
+    /** @var  $archiveService OwnerBillReportArchiveService */
+    private $archiveService;
+
+    /**
+     * SettlementBillStoreFeeReportController constructor.
+     */
+    public function __construct()
+    {
+        $this->service = app('OwnerStoreFeeReportService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+    public function index(Request $request)
+    {
+
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        list($reports, $totalAmount, $totalFee, $owner_price_operation_fees) = $this->service->get([
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this->service::TYPE,
+        ]);
+        $owner_price_operation_fees = $this->buildOwnerPriceOperationFees($reports, $owner_price_operation_fees);
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month, $owner_id);
+        return view('finance.settlementBills.storeFee.report.index',
+            compact('owners', 'owner', 'isArchived', 'request', 'totalAmount', 'totalFee', 'owner_price_operation_fees'));
+    }
+
+    public function export(Request $request)
+    {
+        $this->service = app('OwnerStoreFeeReportService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        list($reports, $totalAmount, $totalFee, $owner_price_operation_fees) = $this->service->get([
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this->service::TYPE,
+        ]);
+        $json = [];
+        foreach ($reports as $report) {
+            $operation = $owner_price_operation_fees->firstWhere('work_name', $report['work_name']);
+            $json[] = [
+                $report['work_name'],
+                $report['unit_price'],
+                $report['amount'],
+                $operation['fee'],
+            ];
+        }
+        $row = ['名称', '单价', '数量', '合计'];
+        return Export::make($row, $json, "入库费合计");
+    }
+
+    /**
+     * @param $reports
+     * @param $owner_price_operation_fees
+     * @return \Illuminate\Support\Collection|Collection
+     */
+    private function buildOwnerPriceOperationFees($reports, $owner_price_operation_fees)
+    {
+        $result = [];
+        $reports = $reports->groupBy('work_name');
+        foreach ($owner_price_operation_fees as $price_operation) {
+            $price_operation['data'] = $reports[$price_operation['work_name']];
+            $result[] = $price_operation;
+        }
+        return collect($result);
+    }
+}

+ 58 - 0
app/Http/Controllers/SettlementBillStoreOutFeeDetailController.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Interfaces\SettlementBillControllerInterface;
+use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerStoreOutFeeDetailService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillStoreOutFeeDetailController extends Controller implements SettlementBillControllerInterface
+{
+    use SettlementBillTrait;
+
+    /** @var OwnerStoreOutFeeDetailService $service */
+    private $service;
+
+    /** @var OwnerBillReportArchiveService $archiveService */
+    private $archiveService;
+
+    public function __construct()
+    {
+        $this->service = app('OwnerStoreOutFeeDetailService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $details = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'paginateParams' => $paginateParams,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.storeOutFee.detail.index', compact('details', 'paginateParams', 'owners', 'owner', 'request'));
+    }
+
+    public function export(Request $request)
+    {
+        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 = $query->get();
+        $json = $this->service->buildExport($details);
+        $row = ['作业时间', '作业名称', '上游单号', '订单号', '商家编码', '商品条码', '商品名称', '商品数量', '单价', '价格描述', '合计'];
+        return Export::make($row, $json, "出库费明细");
+    }
+}

+ 87 - 0
app/Http/Controllers/SettlementBillStoreOutFeeReportController.php

@@ -0,0 +1,87 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Interfaces\SettlementBillControllerInterface;
+use App\Owner;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerStoreOutFeeReportService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillStoreOutFeeReportController extends Controller implements SettlementBillControllerInterface
+{
+
+    use SettlementBillTrait;
+
+    /* @var OwnerStoreOutFeeReportService $service */
+    private $service;
+
+    /** @var  $archiveService OwnerBillReportArchiveService */
+    private $archiveService;
+
+    /**
+     * OwnerStoreOutFeeReportController constructor.
+     */
+    public function __construct()
+    {
+        $this->service = app('OwnerStoreOutFeeReportService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+
+    public function index(Request $request)
+    {
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        list($reports, $work_name_fee_total, $fee_total) = $this->service->get([
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this->service::TYPE,
+        ]);
+
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month, $owner_id);
+        $work_name_fee_total = collect($this->buildWorkNameFeeTotal($reports, $work_name_fee_total));
+        return view('finance.settlementBills.storeOutFee.report.index',
+            compact('owners', 'owner', 'isArchived', 'request', 'work_name_fee_total', 'fee_total'));
+    }
+
+    public function export(Request $request)
+    {
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        list($reports, $work_name_fee_total, $fee_total) = $this->service->get([
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this->service::TYPE,
+        ]);
+        $json = [];
+        $work_name_fee_total = collect($this->buildWorkNameFeeTotal($reports, $work_name_fee_total));
+        foreach ($work_name_fee_total as $work_name_fee_total_item) {
+            foreach ($work_name_fee_total_item['data'] as $data_item) {
+                $json[] = [
+                    $work_name_fee_total_item['work_name'],
+                    $data_item['step'],
+                    $data_item['unit_price'] . '/' . $data_item['unit']['name'] ?? '',
+                    $data_item['amount'],
+                    $work_name_fee_total_item['fee'],
+                ];
+            }
+        }
+        $row = ['作业名称', '阶梯', '单价', '数量', '合计',];
+        return Export::make($row, $json, "出库费合计");
+    }
+
+    private function buildWorkNameFeeTotal($reports, $work_name_fee_total): array
+    {
+        $result = [];
+        $reports_grouped = $reports->groupBy('work_name');
+        foreach ($work_name_fee_total as $work_name_fee_total_item) {
+            $work_name_fee_total_item['data'] = $reports_grouped[$work_name_fee_total_item['work_name']] ?? [];
+            $result[] = $work_name_fee_total_item;
+        }
+        return $result;
+    }
+}

+ 80 - 0
app/Http/Controllers/SettlementBillSundryFeeController.php

@@ -0,0 +1,80 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Interfaces\SettlementBillControllerInterface;
+use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerSundryFeeDetailService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillSundryFeeController extends Controller implements SettlementBillControllerInterface
+{
+    use SettlementBillTrait;
+
+    /** @var OwnerBillReportArchiveService $archiveService */
+    private $archiveService;
+
+    /** @var OwnerSundryFeeDetailService $service */
+    private $service;
+
+    /**
+     * OwnerSundryFeeDetailSettlementBillController constructor.
+     */
+    public function __construct()
+    {
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $this->service = app('OwnerSundryFeeDetailService');
+    }
+
+
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $owner_sundry_fee_details = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'paginateParams' => $paginateParams,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.sundryFee.index', compact('owner_sundry_fee_details', 'paginateParams', 'owners', 'owner', 'request', 'isArchived'));
+    }
+
+
+    public function export(Request $request)
+    {
+        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 = $query->get();
+        $row = ['货主', '日期', '作业类型', '费用描述', '快递单号', '承运商', '数量', '单价', '收费金额', '备注'];
+        $json = [];
+        foreach ($details as $detail) {
+            $json[] = [
+                $detail->owner->name ?? '',
+                $detail->created_at ?? '',
+                $detail->type ?? '',
+                $detail->fee_explain ?? '',
+                $detail->logistic_name ?? '',
+                $detail->logistic->name ?? '',
+                $detail->amount ?? '',
+                $detail->price ?? '',
+                $detail->fee ?? '',
+                $detail->remark ?? '',
+            ];
+        }
+        return Export::make($row, $json, "杂项费");
+    }
+}

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

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Owner;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerDischargeTaskSettlementBillService;
+use App\Traits\SettlementBillTrait;
+use Illuminate\Http\Request;
+use Oursdreams\Export\Export;
+
+class SettlementBillUnloadFeeController extends Controller implements \App\Interfaces\SettlementBillControllerInterface
+{
+    use SettlementBillTrait;
+
+
+    /** @var OwnerDischargeTaskSettlementBillService $service */
+    private $service;
+
+    /** @var OwnerBillReportArchiveService $archiveService */
+    private $archiveService;
+
+
+    /**
+     * OwnerDischargeTaskSettlementBillController constructor.
+     */
+    public function __construct()
+    {
+        $this->service = app('OwnerDischargeTaskSettlementBillService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        list($details, $totalFee) = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'paginateParams' => $paginateParams,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.unloadFee.index', compact('details', 'paginateParams', 'owners', 'owner', 'request', 'isArchived', 'totalFee'));
+
+    }
+
+    public function export(Request $request)
+    {
+        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 = $query->get();
+        $json = $this->service->buildExport($details);
+        $row = ['日期', '作业类型', '入库单号', '数量', '单位', '单价', '收费', '收入描述', '支出吗描述'];
+        return Export::make($row, $json, "卸货费");
+    }
+}

+ 54 - 0
app/Http/Controllers/SettlementIndemnityFeeController.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Owner;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\SettlementIndemnityFeeService;
+use Illuminate\Http\Request;
+
+class SettlementIndemnityFeeController extends Controller implements \App\Interfaces\SettlementBillControllerInterface
+{
+
+    use \App\Traits\SettlementBillTrait;
+
+    /** @var SettlementIndemnityFeeService $service */
+    private $service;
+
+    /** @var OwnerBillReportArchiveService $archiveService */
+    private $archiveService;
+
+
+    /**
+     * OwnerDischargeTaskSettlementBillController constructor.
+     */
+    public function __construct()
+    {
+        $this->service = app('SettlementIndemnityFeeService');
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+    //
+    public function index(Request $request)
+    {
+        $paginateParams = $request->input();
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $details = $this->service->get([
+            'counting_month' => $counting_month,
+            'owner_id' => $owner_id,
+            'paginateParams' => $paginateParams,
+        ]);
+        $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
+        $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
+        $isArchived = $this->archiveService->isArchived($counting_month, $owner_id, $this->service::TYPE);
+        $request = $this->buildRequest($request, $counting_month,$owner_id);
+        return view('finance.settlementBills.indemnityFee.index', compact('details', 'paginateParams', 'owners', 'owner', 'request', 'isArchived'));
+    }
+
+    public function export(Request $request)
+    {
+
+    }
+
+
+}

+ 57 - 73
app/Http/Controllers/StationController.php

@@ -2,22 +2,17 @@
 
 
 namespace App\Http\Controllers;
 namespace App\Http\Controllers;
 
 
+use App\Components\AsyncResponse;
 use App\Station;
 use App\Station;
 use App\StationTypeBinMonitor;
 use App\StationTypeBinMonitor;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Builder;
-use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
 
 
 class StationController extends Controller
 class StationController extends Controller
 {
 {
-    /**
-     * Display a listing of the resource.
-     *
-     * @return void
-     */
-    public function index()
-    {
+    use AsyncResponse;
 
 
-    }
     public function monitorIndex()
     public function monitorIndex()
     {
     {
         $stations = Station::query()->with('stationType:name','parent:name')->whereHas('stationType',function($query){
         $stations = Station::query()->with('stationType:name','parent:name')->whereHas('stationType',function($query){
@@ -27,34 +22,8 @@ class StationController extends Controller
         return view('station.monitor.index',compact('stations'));
         return view('station.monitor.index',compact('stations'));
     }
     }
 
 
-    /**
-     * Show the form for creating a new resource.
-     *
-     * @return \Illuminate\Http\Response
-     */
-    public function create()
-    {
-        //
-    }
-
-    /**
-     * Store a newly created resource in storage.
-     *
-     * @param  \Illuminate\Http\Request  $request
-     * @return \Illuminate\Http\Response
-     */
-    public function store(Request $request)
-    {
-        //
-    }
-
-    public function show(Station $station)
-    {
-        //
-    }
     public function monitorShow(Station $station)
     public function monitorShow(Station $station)
     {
     {
-//        $stationTypeBinMonitor = StationTypeBinMonitor::query()->where("station_id",$station->id)->first();
         $station->loadMissing([
         $station->loadMissing([
             "stationTasks_today.stationTaskCommodities.commodity.barcodes",
             "stationTasks_today.stationTaskCommodities.commodity.barcodes",
             "stationTasks_today.stationTaskCommodities.stationTaskMaterialBox",
             "stationTasks_today.stationTaskCommodities.stationTaskMaterialBox",
@@ -71,50 +40,65 @@ class StationController extends Controller
             ]);
             ]);
             $station->load("stationTypeBinMonitor");
             $station->load("stationTypeBinMonitor");
         }
         }
-//        dd(
-//            data_get($station['stationTasks_today'],'*.id')
-//            ,data_get($station['stationTasks_today'],'*.stationTaskBatches.*.batch.code')
-//            ,data_get($station['stationTasks_today'],'*.stationTaskBatches.*.id')
-//            ,data_get($station['stationTasks_today'],'*.stationTaskBatches.*.batch.id')
-//            ,data_get(data_get($station['stationTasks_today'],'*.stationTaskCommodities')[7],'*.id')
-//            ,data_get(data_get($station['stationTasks_today'],'*.stationTaskCommodities')[9],'*.id')
-//        );
-//        $station=$station->toJson();
         return view('station.monitor.show',compact('station'));
         return view('station.monitor.show',compact('station'));
     }
     }
 
 
-    /**
-     * Show the form for editing the specified resource.
-     *
-     * @param  \App\Station  $station
-     * @return \Illuminate\Http\Response
-     */
-    public function edit(Station $station)
-    {
-        //
-    }
-
-    /**
-     * Update the specified resource in storage.
-     *
-     * @param  \Illuminate\Http\Request  $request
-     * @param  \App\Station  $station
-     * @return \Illuminate\Http\Response
-     */
-    public function update(Request $request, Station $station)
+    public function getVisual()
     {
     {
-        //
+        $arr = \request("arr");
+        $cacheKey = "loadBoxMonitor_".$arr[0][0];
+        if (Cache::tags("loadBoxMonitor")->has($cacheKey))$this->success(Cache::tags("loadBoxMonitor")->get($cacheKey));
+        $res = [];
+        foreach ($arr as $item){
+            $query = DB::connection("mysql_haiRobotics")->table("ks_bin")->select("ks_bin_code");
+            foreach ($item as $value)$query->orWhere("ks_bin_space_code",'like',$value);
+            $codes = [];
+            $query->get()->each(function ($bin)use(&$codes){
+                $codes[] = "'".$bin->ks_bin_code."'";
+            });
+            if (!$codes){$res[] = 100;continue;}
+            $len = count($codes);
+            $codes = "(".implode(",",$codes).")";
+            $sql = <<<SQL
+SELECT COUNT(*) count FROM (SELECT SUM(QTY) qty FROM INV_LOT_LOC_ID WHERE
+TRACEID = '*' AND LOCATIONID IN {$codes} GROUP BY LOCATIONID) inv WHERE INV.qty!=0
+SQL;
+            $count = DB::connection("oracle")->selectOne(DB::raw($sql))->count;
+            //$res[] = intval($count/$len*1000)/10;
+            $res[] = [$len,$count];
+        }
+        Cache::tags("loadBoxMonitor")->put($cacheKey,$res,1800);
+        $this->success($res);
     }
     }
 
 
-    /**
-     * Remove the specified resource from storage.
-     *
-     * @param  \App\Station  $station
-     * @return \Illuminate\Http\Response
-     */
-    public function destroy(Station $station)
+    public function getDetail()
     {
     {
-        //
+        $arr = \request("arr");
+        $cacheKey = "loadBoxMonitorDetail_".$arr[0];
+        if (Cache::tags("loadBoxMonitor")->has($cacheKey))$this->success(Cache::tags("loadBoxMonitor")->get($cacheKey));
+        $ks = DB::connection("mysql_haiRobotics")->table("ks_bin")->select("ks_bin_code","ks_bin_space_code")
+            ->whereIn("ks_bin_space_code",$arr)->get();
+        $res = [];
+        $codes = [];
+        foreach ($ks as $k){
+            $res[$k->ks_bin_code] = $k->ks_bin_space_code;
+            $codes[] = $k->ks_bin_code;
+        }
+        $locations = [];
+        DB::connection("oracle")->table("INV_LOT_LOC_ID")->selectRaw("locationid,SUM(qty) qty")
+            ->where("traceid","*")
+            ->whereIn("locationid",$codes)->groupByRaw("locationid")->get()->each(function ($inv)use(&$locations,&$res){
+                $locations[] = [
+                    "location"  => $res[$inv->locationid],
+                    "status"    => $inv->qty>0,
+                ];
+                unset($res[$inv->locationid]);
+            });
+        if ($res)foreach ($res as $item)$locations[] = [
+            "location"  => $item,
+            "status"    => false,
+        ];
+        Cache::tags("loadBoxMonitor")->put($cacheKey,$locations,1800);
+        $this->success($locations);
     }
     }
-
 }
 }

+ 243 - 82
app/Http/Controllers/StorageController.php

@@ -6,18 +6,20 @@ use App\Commodity;
 use App\CommodityMaterialBoxModel;
 use App\CommodityMaterialBoxModel;
 use App\Components\AsyncResponse;
 use App\Components\AsyncResponse;
 use App\MaterialBox;
 use App\MaterialBox;
+use App\MaterialBoxCommodity;
 use App\MaterialBoxModel;
 use App\MaterialBoxModel;
 use App\Owner;
 use App\Owner;
+use App\Services\LogService;
 use App\Station;
 use App\Station;
 use App\StationTask;
 use App\StationTask;
 use App\StationTaskMaterialBox;
 use App\StationTaskMaterialBox;
-use App\Storage;
 use App\StoreItem;
 use App\StoreItem;
 use App\TaskTransaction;
 use App\TaskTransaction;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Foundation\Auth\AuthenticatesUsers;
 use Illuminate\Foundation\Auth\AuthenticatesUsers;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Validator;
 use Illuminate\Support\Facades\Validator;
@@ -29,6 +31,7 @@ class StorageController extends Controller
 
 
     public function putShelf()
     public function putShelf()
     {
     {
+        $this->error("停用缓存架上架,联系管理员开启");
         $this->gate("入库管理-入库-缓存架入库");
         $this->gate("入库管理-入库-缓存架入库");
         $asn = \request("asn");
         $asn = \request("asn");
         $ide = \request("ide");
         $ide = \request("ide");
@@ -36,16 +39,12 @@ class StorageController extends Controller
         $amount = (int)\request("amount");
         $amount = (int)\request("amount");
         //check info
         //check info
         if (!$asn || !$ide || !$barCode || !$amount)$this->error("信息不完整");
         if (!$asn || !$ide || !$barCode || !$amount)$this->error("信息不完整");
-        $fromLocation = app("MaterialBoxService")->getBoxLocation($ide);
-        if (!$fromLocation)$this->error("WAS无此库位信息");
-        $box = MaterialBox::query()->where("code",$ide)->first();
+        $box = MaterialBox::query()->with("station")->where("code",$ide)->first();
         if (!$box)$this->error("WAS无此料箱");
         if (!$box)$this->error("WAS无此料箱");
+        if (!$box->station)$this->error("WAS无此库位信息");
+        if (!app("StationService")->isCacheShelfLocation($box->station))$this->error("非缓存架库位");
+        $fromLocation = $box->station->code; //源库位
 
 
-        //库存相关信息
-        /** @var Station|\stdClass $station */
-        $station = Station::query()->firstOrCreate(["code"=>$fromLocation],[
-            'name' => $fromLocation, 'code' => $fromLocation, 'station_type_id' => 5
-        ]);
         $item = StoreItem::query()->whereHas("store",function (Builder $query){
         $item = StoreItem::query()->whereHas("store",function (Builder $query){
             $query->where("asn_code",request("asn"));
             $query->where("asn_code",request("asn"));
         })->whereHas("commodity",function (Builder $query)use($barCode){
         })->whereHas("commodity",function (Builder $query)use($barCode){
@@ -53,6 +52,7 @@ class StorageController extends Controller
                 $query->where("code",$barCode);
                 $query->where("code",$barCode);
             });
             });
         })->first();
         })->first();
+        if (!$item)$this->error("WAS无此ASN单信息");
         //get flux
         //get flux
         $tasks = app("StorageService")->getFluxTask($asn,$barCode,$amount);
         $tasks = app("StorageService")->getFluxTask($asn,$barCode,$amount);
         if (!$tasks)$this->error("该单无上架任务或不存在");
         if (!$tasks)$this->error("该单无上架任务或不存在");
@@ -60,7 +60,7 @@ class StorageController extends Controller
         DB::beginTransaction(); //总体事务 回滚WAS错误操作
         DB::beginTransaction(); //总体事务 回滚WAS错误操作
         try{
         try{
             //库存记录
             //库存记录
-            if (!app("StorageService")->enterWarehouse($station->id, $box->id, $item->commodity_id ?? null, $amount, $box->material_box_model_id))$this->error("库存异常");
+            if (!app("StorageService")->enterWarehouse( $box->id, $item->commodity_id, $amount, $box->material_box_model_id))$this->error("库存异常");
 
 
             DB::connection("oracle")->transaction(function ()use($tasks,$ide){ //单体嵌套事务 回滚FLUX失败任务
             DB::connection("oracle")->transaction(function ()use($tasks,$ide){ //单体嵌套事务 回滚FLUX失败任务
                 foreach ($tasks as $task)if (!app("StorageService")->fluxPA($task,$ide)){
                 foreach ($tasks as $task)if (!app("StorageService")->fluxPA($task,$ide)){
@@ -74,11 +74,10 @@ class StorageController extends Controller
             $this->error($e->getMessage());
             $this->error($e->getMessage());
         }
         }
         //亮灯
         //亮灯
-        app("CacheShelfService")->_stationCacheLightOn($fromLocation,$ide);
+        app("CacheShelfService")->lightUp($fromLocation,'1','0',["detail01"=>$ide,"qty01"=>$amount]);
 
 
-        $maximum = app("CommodityMaterialBoxModelService")->getMaximum($box->material_box_model_id,$item->commodity_id ?? null);
-        if ($maximum && $maximum<$amount)app("CommodityMaterialBoxModelService")->setMaximum($box->material_box_model_id,$item->commodity_id ?? null,$amount);
-        $this->success(["model" => $box->material_box_model_id,"commodity" => $item->commodity_id ?? null, "maximum" => $maximum]);
+        $maximum = app("CommodityMaterialBoxModelService")->getMaximum($box->material_box_model_id,$item->commodity_id);
+        $this->success(["model" => $box->material_box_model_id,"commodity" => $item->commodity_id, "maximum" => $maximum]);
     }
     }
 
 
     public function setMaximum()
     public function setMaximum()
@@ -96,15 +95,10 @@ class StorageController extends Controller
         $item = app("StoreItemService")->getMaxAvailableDetail(request("asn"),request("barCode"));
         $item = app("StoreItemService")->getMaxAvailableDetail(request("asn"),request("barCode"));
         if (!$item)$this->error("无此单据记录");
         if (!$item)$this->error("无此单据记录");
         $models = CommodityMaterialBoxModel::query()->where("commodity_id",$item->commodity_id)->get();
         $models = CommodityMaterialBoxModel::query()->where("commodity_id",$item->commodity_id)->get();
-        if ($models->count()==0)$this->error("商品首入,请使用缓存架空箱入库");
-        foreach ($models as $model){
-            $result = app("StorageService")->getHalfBoxLocation($model,$item,request("asn"));
-            if ($result){
-                $result->maximum = $model->maximum-$result->amount;
-                $this->success($result);
-            }
-        }
-        $this->success(["need"=>$models[0]->maximum,"material_box_model_id"=>$models[0]->material_box_model_id,"commodity_id"=>$item->commodity_id]);
+        if ($models->count()==0)$this->success(["material_box_model_id"=>null]);
+        $map = [];
+        foreach ($models as $model)$map[$model->material_box_model_id] = $model;
+        $this->getMaterBoxModel($item,$map);
     }
     }
 
 
     /**
     /**
@@ -131,13 +125,26 @@ sql;
         $boxes = request("boxes");
         $boxes = request("boxes");
         //清理任务
         //清理任务
         $data = '';
         $data = '';
-        $occupy = Storage::query()->with("station:id,code")->whereIn("station_id",Station::query()->select("id")->whereIn("code",$boxes))->where("status",1)->get();
+        //剔除准备执行任务但没有真正开始执行的待定库位
+        $occupy = Station::query()->select("id")->whereIn("code",$boxes)->where("status",1)->get();
         foreach ($occupy as $item){
         foreach ($occupy as $item){
-            unset($boxes[array_search($item->station->code,$boxes)]);
-            $data .= '“'.$item->station->code.'”,';
+            unset($boxes[array_search($item->code,$boxes)]);
+            $data .= '“'.$item->code.'”,';
         }
         }
         if ($occupy->count()>0){
         if ($occupy->count()>0){
-            $data .= "存在任务待处理,无法调取";
+            $data .= "存在任务待处理,无法调取  ";
+            $boxes = array_values($boxes);
+        }
+        //剔除存在任务的库位
+        $tasks = StationTaskMaterialBox::query()->with("station:id,code")
+            ->whereIn("station_id",Station::query()->select("id")->whereIn("code",$boxes))
+            ->whereNotIn("status",["完成","取消"])->get();
+        foreach ($tasks as $task){
+            unset($boxes[array_search($task->station->code,$boxes)]);
+            $data .= '“'.$task->station->code.'”,';
+        };
+        if ($tasks->count()>0){
+            $data .= "任务排队中,无法调取";
             $boxes = array_values($boxes);
             $boxes = array_values($boxes);
         }
         }
         //重新调取料箱
         //重新调取料箱
@@ -155,78 +162,88 @@ sql;
         $this->gate("入库管理-入库-半箱补货入库");
         $this->gate("入库管理-入库-半箱补货入库");
         $boxId = request("material_box_id");
         $boxId = request("material_box_id");
         $modelId = request("material_box_model_id");
         $modelId = request("material_box_model_id");
+        if (!$modelId)$this->error("商品未设定库存上限");
         //获取目标库位
         //获取目标库位
         $station = app("StationService")->getMirrorMappingLocation(request("station"));
         $station = app("StationService")->getMirrorMappingLocation(request("station"));
         if (!$station)$this->error("未知库位");
         if (!$station)$this->error("未知库位");
-        $occupyTask = StationTaskMaterialBox::query()->where("station_id",$station->id)->whereNotIn("status",["完成","取消"])->first();
-        if ($occupyTask)$this->error("库位存在任务未处理完成");
+        $isAvailable = app("StationService")->isAvailable($station);
+        if (!$isAvailable)$this->error("库存被占用或存在任务未处理");
         $amount = app("StorageService")->checkPutAmount(request("asn"),request("barCode"));
         $amount = app("StorageService")->checkPutAmount(request("asn"),request("barCode"));
         if ($amount<request("amount"))$this->error("待上架数量不足,最大可上数量为{$amount}");
         if ($amount<request("amount"))$this->error("待上架数量不足,最大可上数量为{$amount}");
+
+        //发起取箱任务
+        $exe = function ($boxId)use($station){
+            DB::beginTransaction();
+            $collection = new Collection();
+            $task = StationTask::query()->create([
+                'status' => "待处理",
+                'station_id' => $station->id,
+            ]);
+            $collection->add(StationTaskMaterialBox::query()->create([
+                'station_id' => $station->id,
+                'material_box_id'=>$boxId,
+                'status'=>"待处理",
+                'type' => '取',
+                'station_task_id' => $task->id,
+            ]));
+            if (!app("ForeignHaiRoboticsService")->fetchGroup($station->code,$collection,'','立架出至缓存架'))$this->error("呼叫机器人失败");
+            //生成临时任务事务
+            TaskTransaction::query()->create([
+                "doc_code" => request("asn"),
+                "bar_code" => request("barCode"),
+                "fm_station_id" => $station->id,
+                "material_box_id" => $boxId,
+                "commodity_id" => request("commodity_id"),
+                "amount" => request("amount"),
+                "type" => "入库",
+                "user_id" => Auth::id(),
+                "mark" => 1
+            ]);
+            DB::commit();
+            //亮灯
+            app("CacheShelfService")->lightUp($station->code,'3','2');
+            app("StationService")->locationOccupy($station->code);//占用库位
+            Cache::forever("CACHE_SHELF_OCCUPANCY_{$station->id}",true);
+        };
+        if ($boxId && app("MaterialBoxService")->checkUsableBox($boxId))$this->success($exe($boxId));
+        $item = app("StoreItemService")->getMaxAvailableDetail(request("asn"),request("barCode"));
+        if (!$item)$this->error("无此单据记录");
+        $models = app("MaterialBoxModelService")->getModelSortedByOwner($item->store->owner_id);
+        $models->load(["commodity"=>function($query)use($item){
+            $query->where("commodity_id",$item->commodity_id);
+        }]);
         //获取料箱
         //获取料箱
-        if ($boxId && !app("MaterialBoxService")->checkUsableBox($boxId)){
+        if ($boxId){
             $blacklist = [$boxId];
             $blacklist = [$boxId];
             $boxId = null;
             $boxId = null;
             //料箱存在且不可用
             //料箱存在且不可用
-            $models = CommodityMaterialBoxModel::query()->where("commodity_id",request("commodity_id"))->get();
-            $item = app("StoreItemService")->getMaxAvailableDetail(request("asn"),request("barCode"));
-            if (!$item)$this->error("无此单据记录");
+            /** @var \Illuminate\Database\Eloquent\Collection $models */
+
             foreach ($models as $model){
             foreach ($models as $model){
+                if (!$model->commodity)continue;
                 //料箱不可用寻找新料箱
                 //料箱不可用寻找新料箱
-                $result = app("StorageService")->getHalfBoxLocation($model,$item,request("asn"),$blacklist);
+                $result = app("StorageService")->getHalfBoxLocation($model->commodity,$item,request("asn"),$blacklist);
                 while ($result){
                 while ($result){
                     //料箱可用并且数量符合本次半箱数量 跳出
                     //料箱可用并且数量符合本次半箱数量 跳出
                     if (app("MaterialBoxService")->checkUsableBox($result->material_box_id)
                     if (app("MaterialBoxService")->checkUsableBox($result->material_box_id)
-                        && $model->maximum-$result->amount>=request("amount")){$boxId = $result->material_box_id;break;}
+                        && $model->maximum-$result->amount>=request("amount"))$this->success($exe($result->material_box_id));
                     else $blacklist[] = $result->material_box_id;
                     else $blacklist[] = $result->material_box_id;
                     //否则黑名单此料箱继续查找 直至料箱为空
                     //否则黑名单此料箱继续查找 直至料箱为空
-                    $result = app("StorageService")->getHalfBoxLocation($model,$item,request("asn"),$blacklist);
+                    $result = app("StorageService")->getHalfBoxLocation($model->commodity,$item,request("asn"),$blacklist);
                 }
                 }
             }
             }
         }
         }
         //料箱不存在且该商品有过入库记录 拿取空箱
         //料箱不存在且该商品有过入库记录 拿取空箱
-        if (!$boxId){
-            if (!$modelId){
-                $box = null;
-                $models = CommodityMaterialBoxModel::query()->where("commodity_id",request("commodity_id"))->get();
-                foreach ($models as $model){
-                    $box = app("MaterialBoxService")->getAnEmptyBox([],$model->material_box_model_id);
-                    if($box)break;
-                }
-            }else $box = app("MaterialBoxService")->getAnEmptyBox([],$modelId);
-            if (!$box)$this->error("无可用料箱");
-            $boxId = $box->id;
-        }
-        //发起取箱任务
-        DB::beginTransaction();
-        $collection = new Collection();
-        $task = StationTask::query()->create([
-            'status' => "待处理",
-            'station_id' => $station->id,
-        ]);
-        $collection->add(StationTaskMaterialBox::query()->create([
-            'station_id' => $station->id,
-            'material_box_id'=>$boxId,
-            'status'=>"待处理",
-            'type' => '取',
-            'station_task_id' => $task->id,
-        ]));
-        if (!app("ForeignHaiRoboticsService")->fetchGroup($station->code,$collection,'','立架出至缓存架'))$this->error("呼叫机器人失败");
-        //生成临时任务事务
-        TaskTransaction::query()->create([
-            "doc_code" => request("asn"),
-            "bar_code" => request("barCode"),
-            "fm_station_id" => $station->id,
-            "material_box_id" => $boxId,
-            "commodity_id" => request("commodity_id"),
-            "amount" => request("amount"),
-            "type" => "入库",
-            "user_id" => Auth::id(),
-            "mark" => 1
-        ]);
-        DB::commit();
-        //亮灯
-        app("CacheShelfService")->stationLightUp($station->code,null,'2');
-        $this->success();
+        if (!$modelId){
+            $box = null;
+            foreach ($models as $model){
+                if (!$model->commodity)continue;
+                $box = app("MaterialBoxService")->getAnEmptyBox($model);
+                if($box)break;
+            }
+        }else $box = app("MaterialBoxService")->getAnEmptyBox(MaterialBoxModel::query()->find($modelId));
+        if (!$box)$this->error("无可用料箱");
+        $this->success($exe($box->id));
     }
     }
 
 
     /**
     /**
@@ -244,7 +261,8 @@ sql;
             ->where("type","入库")->where("mark",1)->where("status",0)->first();
             ->where("type","入库")->where("mark",1)->where("status",0)->first();
         if (!$task)$this->error("无任务存在");
         if (!$task)$this->error("无任务存在");
         $task->update(["amount" => DB::raw("amount - {$amount}")]);
         $task->update(["amount" => DB::raw("amount - {$amount}")]);
-        $storage = Storage::query()->where("material_box_id",$task->material_box_id)->first();
+        $storage = MaterialBoxCommodity::query()->where("material_box_id",$task->material_box_id)
+            ->where("commodity_id",$task->commodity_id)->first();
         $maximum = (($storage->amount ?? 0)+$task->amount)-$amount;
         $maximum = (($storage->amount ?? 0)+$task->amount)-$amount;
         CommodityMaterialBoxModel::query()->where("material_box_model_id",$task->materialBox->material_box_model_id)
         CommodityMaterialBoxModel::query()->where("material_box_model_id",$task->materialBox->material_box_model_id)
             ->where("commodity_id",$task->commodity_id)->update(["maximum"=>$maximum]);
             ->where("commodity_id",$task->commodity_id)->update(["maximum"=>$maximum]);
@@ -273,9 +291,9 @@ sql;
                 "name" => $inv->customerid,
                 "name" => $inv->customerid,
             ]);
             ]);
             $commodity = Commodity::query()->where("owner_id",$owner->id)->where("sku",$inv->sku)->first();
             $commodity = Commodity::query()->where("owner_id",$owner->id)->where("sku",$inv->sku)->first();
-            $s = \App\Storage::query()->where("material_box_id",$materialBox->id)
+            $s = MaterialBoxCommodity::query()->where("material_box_id",$materialBox->id)
                 ->where("commodity_id",$commodity->id)->first();
                 ->where("commodity_id",$commodity->id)->first();
-            if (!$s)\App\Storage::query()->create([
+            if (!$s)MaterialBoxCommodity::query()->create([
                 "material_box_id" => $materialBox->id,
                 "material_box_id" => $materialBox->id,
                 "commodity_id" => $commodity->id,
                 "commodity_id" => $commodity->id,
                 "amount" => $inv->qty,
                 "amount" => $inv->qty,
@@ -304,4 +322,147 @@ sql;
     {
     {
         return 'name';
         return 'name';
     }
     }
+
+    /**
+     * 库外箱绑定至库位
+     */
+    public function bindBox()
+    {
+        $location = request("location");
+        $box = request("ide");
+        if (!$location || !$box)$this->error("参数传递错误");
+        $task = StationTaskMaterialBox::query()->select("id")->where(function ($query)use($location,$box){
+            /** @var Builder $query */
+            $query->whereHas("station",function ($query)use($location){
+                /** @var Builder $query */
+                $query->where("code",$location);
+            })->orWhereHas("materialBox",function ($query)use($box){
+                /** @var Builder $query */
+                $query->where("code",$box);
+            });
+        })->whereNotIn("status",["完成","取消"])->first();
+        if ($task)$this->error("库位或料箱存在任务待执行,无法放置料箱");
+        $ks = DB::connection("mysql_haiRobotics")->table("ks_bin")->select(DB::raw("1"))
+            ->where("ks_bin_code",$box)->where("status",4)->first();
+        if (!$ks)$this->error("海柔料箱状态异常");
+        DB::beginTransaction();
+        try {
+            $station = Station::query()->where("code",$location)->where("status",0)->first();
+            $box = MaterialBox::query()->where("code",$box)->first();
+            if (!$station || !$box)$this->error("库位或料箱未在WAS记录");
+            $station->update(["material_box_id"=>$box->id]);
+            DB::commit();
+            $this->success();
+        }catch (\Exception $e){
+            DB::rollBack();
+            $this->error($e->getMessage());
+        }
+    }
+
+    public function bindModelIndex(){
+        $models = MaterialBoxModel::query()->get();
+        return view("store.inStorage.boxBindModel",compact("models"));
+    }
+
+    public function searchIde()
+    {
+        $ide = request("ide");
+        $box = MaterialBox::query()->where("code",$ide)->first();
+        if (!$box)$this->error("料箱不存在");
+        $this->success($box->material_box_model_id);
+    }
+
+    public function boxBindModel()
+    {
+        $this->success(MaterialBox::query()->where("code",request("ide"))
+            ->update(["material_box_model_id"=>request("material_box_model_id")]));
+    }
+
+    public function commodityBindModel()
+    {
+        $models = MaterialBoxModel::query()->get();
+        return view("store.inStorage.commodityBindModel",compact("models"));
+    }
+
+    public function getModels()
+    {
+        $this->success(MaterialBoxModel::query()->select("id","code","description","maximum_kind")->get());
+    }
+
+    /**
+     * 设定料箱最大
+     */
+    public function settingModelMaximum()
+    {
+        $insert = function ($commodityId){
+            $in = [];
+            $map = [];
+            $ids = [];
+            foreach (request("models") as $model){
+                $insert[] = [
+                    "commodity_id" => $commodityId,
+                    "material_box_model_id" => $model["id"],
+                    "maximum" => $model["maximum"]
+                ];
+                $map[$model["id"]] = $model;
+                $ids[] = $model["id"];
+            }
+            return array($in,$map,$ids);
+        };
+        if (request("commodityId")){
+            list($in,$map,$ids) = $insert(request("commodityId"));
+            if ($ids){
+                $map = array_flip($ids);
+                foreach (CommodityMaterialBoxModel::query()->whereIn("id",$ids)->lockForUpdate()->get() as $model){
+                    $index = $map[$model->id];
+                    if ($model->maximum != $in[$index]["maximum"])$model->update(["maximum"=>$in[$index]["maximum"]]);
+                    unset($in[$index]);
+                }
+                $in = array_values($in);
+            }
+            if ($in){
+                LogService::log(__CLASS__,__METHOD__,json_encode($in));
+                CommodityMaterialBoxModel::query()->insert($in);
+            }
+            $this->success();
+        }
+        $item = StoreItem::query()->whereHas("store",function (Builder $query){
+            $query->where("asn_code",request("asn"));
+        })->whereHas("commodity",function (Builder $query){
+            $query->whereHas("barcodes",function (Builder $query){
+                $query->where("code",request("barCode"));
+            });
+        })->first();
+        if (!$item)$this->error("商品不存在");
+        list($in,$map,$ids) = $insert($item->store->commodity_id);
+        LogService::log(__CLASS__,__METHOD__,json_encode($in));
+        CommodityMaterialBoxModel::query()->insert($in);
+        $this->getMaterBoxModel($item,$map);
+    }
+
+    private function getMaterBoxModel($item,$map)
+    {
+        $models = app("MaterialBoxModelService")->getModelSortedByOwner($item->store->owner_id);
+        foreach ($models as $model){
+            if (!isset($map[$model->id]))continue;
+            $result = app("StorageService")->getHalfBoxLocation($map[$model->id],$item,$item->store->asn_code);
+            if (!$result)continue;
+            $result->maximum = $model->maximum-$result->amount;
+            $this->success($result);
+        }
+        $this->success(["need"=>$models[0]->maximum,"material_box_model_id"=>$models[0]->material_box_model_id,"commodity_id"=>$item->commodity_id]);
+    }
+
+    /**
+     * 根据条码检索商品
+     */
+    public function searchBarCode()
+    {
+        $commodities = Commodity::query()->whereHas("barcodes",function (Builder $query){
+            $query->where("code",request("barCode"));
+        })->get();
+        if (!$commodities->count())$this->error("库内无此商品信息");
+        if ($commodities->count()>1)$commodities->load("owner");
+        $this->success($commodities);
+    }
 }
 }

+ 4 - 7
app/Http/Controllers/StoreController.php

@@ -7,7 +7,6 @@ use App\Owner;
 use App\Services\common\BatchUpdateService;
 use App\Services\common\BatchUpdateService;
 use App\Services\StoreService;
 use App\Services\StoreService;
 use App\Station;
 use App\Station;
-use App\Storage;
 use App\Store;
 use App\Store;
 use App\StoreItem;
 use App\StoreItem;
 use App\Warehouse;
 use App\Warehouse;
@@ -440,11 +439,8 @@ class StoreController extends Controller
      */
      */
     public function cacheRackStorage()
     public function cacheRackStorage()
     {
     {
-        $stations = Station::query()->select("id")->where("parent_id",6);
-        $storages = Storage::query()->with("station:id,code")->whereIn("station_id",$stations)->where(function (Builder $query){
-            $query->whereNotNull("material_box_id")->orWhere("status",1);
-        })->get();
-        return \view("store.inStorage.cacheRackStorage",compact("storages"));
+        $stations = Station::query()->where("parent_id",6)->get();
+        return \view("store.inStorage.cacheRackStorage",compact("stations"));
     }
     }
 
 
     /**
     /**
@@ -452,6 +448,7 @@ class StoreController extends Controller
      */
      */
     public function halfChestStorage()
     public function halfChestStorage()
     {
     {
-        return \view("store.inStorage.halfChestStorage");
+        $stations = app("StationService")->getCacheShelf();
+        return \view("store.inStorage.halfChestStorage",compact("stations"));
     }
     }
 }
 }

File diff suppressed because it is too large
+ 10 - 378
app/Http/Controllers/TestController.php


+ 77 - 8
app/Http/Controllers/WaybillController.php

@@ -74,6 +74,7 @@ class WaybillController extends Controller
         $type=$request->type ?? "";
         $type=$request->type ?? "";
         if ($type==='ZF')$type='直发车';
         if ($type==='ZF')$type='直发车';
         if ($type==='ZX')$type='专线';
         if ($type==='ZX')$type='专线';
+        if ($type==='DBWL')$type='德邦物流';
         return view('transport.waybill.create',['owners'=>$ownerService->getIntersectPermitting(),'type'=>$type]);
         return view('transport.waybill.create',['owners'=>$ownerService->getIntersectPermitting(),'type'=>$type]);
     }
     }
 
 
@@ -88,7 +89,6 @@ class WaybillController extends Controller
 
 
     public function edit($id,LogisticService $logisticService,CarTypeService $carTypeService,UnitService $unitService)
     public function edit($id,LogisticService $logisticService,CarTypeService $carTypeService,UnitService $unitService)
     {
     {
-        //if(!Gate::allows('运输管理-编辑')){ return redirect(url('denied'));  }
         $waybill = app('waybillService')->find($id);
         $waybill = app('waybillService')->find($id);
         if ($waybill->order_id){
         if ($waybill->order_id){
             /** @var Waybill $waybill */
             /** @var Waybill $waybill */
@@ -109,7 +109,10 @@ class WaybillController extends Controller
         $units=$unitService->getSelection();
         $units=$unitService->getSelection();
         $carTypes=$carTypeService->getSelection();
         $carTypes=$carTypeService->getSelection();
         $deliveryType = app('DeliveryTypeService')->getSelection();
         $deliveryType = app('DeliveryTypeService')->getSelection();
-        return view('transport.waybill.edit',['waybill'=>$waybill,'logistics'=>$logisticService->getSelection(["id","name"],"物流"),'cities'=>$cities,'units'=>$units,'carTypes'=>$carTypes,'deliveryTypes'=>$deliveryType]);
+        return view('transport.waybill.edit',['waybill'=>$waybill,'logistics'=>$logisticService->getSelection(["id","name","tag"],"物流"),'cities'=>$cities,'units'=>$units,'carTypes'=>$carTypes,
+            'deliveryTypes'=>$deliveryType,'orderTypes' =>collect(config('api_logistic.DB.prod.orderType')),'transportTypes' => collect(config('api_logistic.DB.prod.transportType'))
+            ,'payTypes' => collect(config('api_logistic.DB.prod.payType')),'backSignBills' => collect(config('api_logistic.DB.prod.backSignBill')),'packageServices' => collect(config('api_logistic.DB.prod.packageService'))
+        ]);
     }
     }
 
 
     public function update(Request $request, $id,WaybillPriceModelService $waybillPriceModelService,
     public function update(Request $request, $id,WaybillPriceModelService $waybillPriceModelService,
@@ -174,11 +177,11 @@ class WaybillController extends Controller
             'user_id'=>Auth::id(),
             'user_id'=>Auth::id(),
         ]);
         ]);
         //todo 若是德邦物流 请求API创建快递单号
         //todo 若是德邦物流 请求API创建快递单号
-        $logistic_ids = Logistic::query()->where('name','like', '德邦%')->pluck('id')->toArray();
-        if (in_array($request['logistic_id'], $logistic_ids)){
-            $row = app('DbOpenService')->getDbOrderNo(['id' => $id]);
-            if ($row == 'false') $msg = '-- 生成德邦快递单号失败,请核实参数重新调度';
-        }
+//        $logistic_ids = Logistic::query()->where('name','like', '德邦%')->where('type','=','物流')->pluck('id')->toArray();
+//        if (in_array($request['logistic_id'], $logistic_ids)){
+//            $res = app('DbOpenService')->getDbOrderNo(['id' => $id]);
+//            $msg =  $res['msg']? "【申请德邦物流单号:".$res['msg']."】"  :'';
+//        }
         return redirect('transport/waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”调度成功 '. ($msg??''));
         return redirect('transport/waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”调度成功 '. ($msg??''));
     }
     }
 
 
@@ -293,12 +296,17 @@ class WaybillController extends Controller
         $validatorData=["logistic_id"=>$logistic_id,"destination_city_id"=>$destination_city_id,
         $validatorData=["logistic_id"=>$logistic_id,"destination_city_id"=>$destination_city_id,
             'carrier_weight'=>$carrier_weight[0],"carrier_weight_unit_id"=>$carrier_weight_unit_id[0],
             'carrier_weight'=>$carrier_weight[0],"carrier_weight_unit_id"=>$carrier_weight_unit_id[0],
             "carrier_weight_other"=>$carrier_weight[1],"carrier_weight_unit_id_other"=>$carrier_weight_unit_id[1]];
             "carrier_weight_other"=>$carrier_weight[1],"carrier_weight_unit_id_other"=>$carrier_weight_unit_id[1]];
-        if (in_array($logistic_id,[14,15,28,29])){
+        if ($logistic_id == 15){
             $flag = 1;
             $flag = 1;
             $validatorData['cargo_name'] = $request->input('cargo_name');
             $validatorData['cargo_name'] = $request->input('cargo_name');
             $validatorData['total_number'] = $request->input('total_number');
             $validatorData['total_number'] = $request->input('total_number');
             $validatorData['total_weight'] = $request->input('total_weight');
             $validatorData['total_weight'] = $request->input('total_weight');
             $validatorData['deliveryType_id'] = $request->input('deliveryType_id');
             $validatorData['deliveryType_id'] = $request->input('deliveryType_id');
+            $validatorData['order_type'] = $request->input('order_type');
+            $validatorData['transport_type'] = $request->input('transport_type');
+            $validatorData['pay_type'] = $request->input('pay_type');
+            $validatorData['back_sign_bill'] = $request->input('back_sign_bill');
+            $validatorData['package_service'] = $request->input('package_service');
         }else $flag = 0;
         }else $flag = 0;
         $errors=Validator::make($validatorData,[
         $errors=Validator::make($validatorData,[
             'logistic_id'=>'required|integer',
             'logistic_id'=>'required|integer',
@@ -311,6 +319,11 @@ class WaybillController extends Controller
             'total_number' => $flag ? 'required|min:0|numeric|max:999999' : '',
             'total_number' => $flag ? 'required|min:0|numeric|max:999999' : '',
             'total_weight' => $flag ? 'required|min:0|numeric|max:999999' : '',
             'total_weight' => $flag ? 'required|min:0|numeric|max:999999' : '',
             'deliveryType_id' => $flag ? 'required' : '',
             'deliveryType_id' => $flag ? 'required' : '',
+            'order_type' => $flag ? 'required' : '',
+            'transport_type' => $flag ? 'required' : '',
+            'pay_type' => $flag ? 'required' : '',
+            'back_sign_bill' => $flag ? 'required' : '',
+            'package_service' => $flag ? 'required' : '',
         ],[
         ],[
             'required'=>':attribute 为必填项',
             'required'=>':attribute 为必填项',
             'max'=>':attribute 字符过多或输入值过大',
             'max'=>':attribute 字符过多或输入值过大',
@@ -330,6 +343,10 @@ class WaybillController extends Controller
             'total_number' =>  '总包裹数',
             'total_number' =>  '总包裹数',
             'total_weight' =>  '总重量',
             'total_weight' =>  '总重量',
             'deliveryType_id' => '送货方式',
             'deliveryType_id' => '送货方式',
+            'order_type' => '下单模式',
+            'transport_type' => '运输方式/产品类型',
+            'pay_type' => '支付方式',
+            'back_sign_bill' => '签收回单',
         ])->errors();
         ])->errors();
         if (count($errors)>0)return ['error'=>$errors];
         if (count($errors)>0)return ['error'=>$errors];
         $result=$this->checkWaybillPriceModel($logistic_id,$destination_city_id,$carrier_weight,$carrier_weight_unit_id);
         $result=$this->checkWaybillPriceModel($logistic_id,$destination_city_id,$carrier_weight,$carrier_weight_unit_id);
@@ -806,6 +823,7 @@ class WaybillController extends Controller
             'carrier_weight_unit_id'=>'sometimes|required_with:carrier_weight',
             'carrier_weight_unit_id'=>'sometimes|required_with:carrier_weight',
             'carrier_weight_other'=>'sometimes|nullable|min:0|numeric|max:999999',
             'carrier_weight_other'=>'sometimes|nullable|min:0|numeric|max:999999',
             'carrier_weight_unit_id_other'=>'sometimes|required_with:carrier_weight_other',
             'carrier_weight_unit_id_other'=>'sometimes|required_with:carrier_weight_other',
+            'deliver_at_date'=>'required',
         ];
         ];
         if ($request->type == '专线'){
         if ($request->type == '专线'){
             $rule['origination_city_id']='required|integer';
             $rule['origination_city_id']='required|integer';
@@ -840,6 +858,7 @@ class WaybillController extends Controller
             'carrier_weight_other'=>'承运商计数二',
             'carrier_weight_other'=>'承运商计数二',
             'warehouse_weight_unit_id_other'=>'仓库技数单位二',
             'warehouse_weight_unit_id_other'=>'仓库技数单位二',
             'carrier_weight_unit_id_other'=>'承运商计数单位二',
             'carrier_weight_unit_id_other'=>'承运商计数单位二',
+            'deliver_at_date'=>'发货日期',
         ]);
         ]);
         return $validator;
         return $validator;
     }
     }
@@ -1017,6 +1036,7 @@ class WaybillController extends Controller
         $waybill = $waybills->first();
         $waybill = $waybills->first();
         $destroys = [];
         $destroys = [];
         $owner = [$waybill->owner_id];
         $owner = [$waybill->owner_id];
+        if (array_search($waybill->status,["未审核","已审核"])===false)$this->error("运单禁止合并");
         for ($i=1;$i<$waybills->count();$i++){
         for ($i=1;$i<$waybills->count();$i++){
             //信息一致性校验
             //信息一致性校验
             $identical = ($waybill->order && ($waybills[$i]->order->consignee_name!=$waybill->order->consignee_name
             $identical = ($waybill->order && ($waybills[$i]->order->consignee_name!=$waybill->order->consignee_name
@@ -1037,6 +1057,7 @@ class WaybillController extends Controller
             $waybill->warehouse_weight += (double)$waybills[$i]->warehouse_weight;
             $waybill->warehouse_weight += (double)$waybills[$i]->warehouse_weight;
             $owner[] = $waybills[$i]->owner_id;
             $owner[] = $waybills[$i]->owner_id;
         }
         }
+        if (strlen($waybill->source_bill)>191 || strlen($waybill->wms_bill_number)>191)$this->error("单号超长,无法合并");
         $owner = array_unique($owner);
         $owner = array_unique($owner);
         if (count($owner)>1)$waybill->merge_owner = implode(',',$owner);
         if (count($owner)>1)$waybill->merge_owner = implode(',',$owner);
         $waybill->update();
         $waybill->update();
@@ -1048,4 +1069,52 @@ class WaybillController extends Controller
         ]);
         ]);
         $this->success($waybill->waybill_number);
         $this->success($waybill->waybill_number);
     }
     }
+
+    /**
+     * 运单拆分
+     */
+    public function waybillSplit(Request $request)
+    {
+        $this->gate("运输管理-编辑");
+        $ids = $request->input("ids");
+        DB::beginTransaction();
+        try {
+            /** @var Collection $waybills */
+            $waybills = Waybill::query()->whereHas("waybillAuditLogs",function ($query){
+                $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);
+                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)]);
+                    $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->update();
+                WaybillAuditLog::query()->create([
+                    'waybill_id'=>$waybill->id,
+                    'audit_stage'=>'拆单返回',
+                    'user_id'=>Auth::id(),
+                ]);
+
+            }
+            DB::commit();
+        }catch (\Exception $e){
+            DB::rollBack();
+            $this->error($e->getMessage());
+        }
+        $this->success(count($ids)==$waybills->count() ? '运单拆单完毕' : '部分运单不符合拆单条件');
+    }
 }
 }

+ 17 - 11
app/Http/Controllers/api/thirdPart/flux/WaybillController.php

@@ -27,7 +27,6 @@ class WaybillController extends Controller
         (new Controller())->log(__METHOD__,__FUNCTION__,'WMS requesting:.'.'|'.json_encode($request->all()));
         (new Controller())->log(__METHOD__,__FUNCTION__,'WMS requesting:.'.'|'.json_encode($request->all()));
         $errors=$this->validatorForNew($request->all())->errors();
         $errors=$this->validatorForNew($request->all())->errors();
         if(count($errors)>0){
         if(count($errors)>0){
-            app('LogService')->log(__METHOD__, 'error_' . __FUNCTION__, json_encode($request->getContent()));
             (new Controller())->log(__METHOD__,'error_'.__FUNCTION__,'fields wrong, see Errors report please.'.'|'.json_encode($request->all()).'|'.json_encode($errors));
             (new Controller())->log(__METHOD__,'error_'.__FUNCTION__,'fields wrong, see Errors report please.'.'|'.json_encode($request->all()).'|'.json_encode($errors));
             return response()->json(['response'=>['return'=>['returnFlag'=>'0','returnCode'=>'0001','returnDesc'=>'消息处理失败:Failure','resultInfo'=>'',
             return response()->json(['response'=>['return'=>['returnFlag'=>'0','returnCode'=>'0001','returnDesc'=>'消息处理失败:Failure','resultInfo'=>'',
                 'errors'=>$errors]]])
                 'errors'=>$errors]]])
@@ -63,6 +62,8 @@ class WaybillController extends Controller
             $owner=Owner::query()->where('code',$receiveInputting['CustomerID'])->first();
             $owner=Owner::query()->where('code',$receiveInputting['CustomerID'])->first();
             if (!$owner){$owner=new Owner(['name'=>$receiveInputting['CustomerID'],'code'=>$receiveInputting['CustomerID']]);$owner->save();}
             if (!$owner){$owner=new Owner(['name'=>$receiveInputting['CustomerID'],'code'=>$receiveInputting['CustomerID']]);$owner->save();}
             $zfList=config('merchantsInfo.waybill.ZFList');
             $zfList=config('merchantsInfo.waybill.ZFList');
+            $type = substr($receiveInputting['CarrierID'],0,2) == 'DB' ? '德邦物流' :
+                (isset($zfList[$receiveInputting['CarrierID']])&&$zfList[$receiveInputting['CarrierID']]?"直发车":"专线");
             $bswasCustomer=OracleBasCustomer::query()->where("customerid",$receiveInputting['CustomerID'])->first();
             $bswasCustomer=OracleBasCustomer::query()->where("customerid",$receiveInputting['CustomerID'])->first();
             if ($bswasCustomer){
             if ($bswasCustomer){
                 $origination=$bswasCustomer->address1;
                 $origination=$bswasCustomer->address1;
@@ -73,11 +74,11 @@ class WaybillController extends Controller
             }
             }
             $recipient_mobile=trim($receiveInputting['C_Tel1'],',');
             $recipient_mobile=trim($receiveInputting['C_Tel1'],',');
             $waybill=new Waybill([
             $waybill=new Waybill([
-                'type'=>isset($zfList[$receiveInputting['CarrierID']])&&$zfList[$receiveInputting['CarrierID']]?"直发车":"专线",
+                'type'=>$type,
                 'waybill_number'=>Uuid::uuid1(),
                 'waybill_number'=>Uuid::uuid1(),
                 'owner_id'=>$owner->id,
                 'owner_id'=>$owner->id,
                 'wms_bill_number'=>$receiveInputting['OrderNo']??'',
                 'wms_bill_number'=>$receiveInputting['OrderNo']??'',
-                'origination'=>isset($origination)?$origination:"",
+                'origination'=>$origination ?? "",
                 'destination'=>$receiveInputting['C_Address1']??'',
                 'destination'=>$receiveInputting['C_Address1']??'',
                 'recipient'=>$receiveInputting['ConsigneeName']??'',
                 'recipient'=>$receiveInputting['ConsigneeName']??'',
                 'recipient_mobile'=>$recipient_mobile??'',
                 'recipient_mobile'=>$recipient_mobile??'',
@@ -109,15 +110,20 @@ class WaybillController extends Controller
                 'audit_stage'=>'创建',
                 'audit_stage'=>'创建',
                 'user_id'=>Auth::id() ?? 0,
                 'user_id'=>Auth::id() ?? 0,
             ]);
             ]);
-            if ($waybill->type=='直发车'){
-                $waybill_number='BSZF'.date ("ymd").str_pad($waybill->id>99999?$waybill->id%99999:$waybill->id,4,"0",STR_PAD_LEFT);
-                $waybill->waybill_number=$waybill_number;
-                $waybill->update();
-            }else{
-                $waybill_number='BSZX'.date ("ymd").str_pad($waybill->id>99999?$waybill->id%99999:$waybill->id,4,"0",STR_PAD_LEFT);
-                $waybill->waybill_number=$waybill_number;
-                $waybill->update();
+            switch ($waybill->type){
+                case "直发车":
+                    $prefix = "BSZF";
+                    break;
+                case "专线":
+                    $prefix = "BSZX";
+                    break;
+                default:
+                    $prefix = "BSDB";
+                    break;
             }
             }
+            $waybill_number=$prefix.date ("ymd").str_pad($waybill->id>99999?$waybill->id%99999:$waybill->id,4,"0",STR_PAD_LEFT);
+            $waybill->waybill_number=$waybill_number;
+            $waybill->update();
             if (!$waybill->order_id && $waybill->wms_bill_number)dispatch(new HandleExceptionWaybill($waybill))->delay(now()->addMinutes(15));
             if (!$waybill->order_id && $waybill->wms_bill_number)dispatch(new HandleExceptionWaybill($waybill))->delay(now()->addMinutes(15));
             //回传FLUX
             //回传FLUX
             $this->accomplishToWMS($waybill);
             $this->accomplishToWMS($waybill);

+ 2 - 1
app/Http/Controllers/api/thirdPart/haiq/HaiRoboticsController.php

@@ -25,7 +25,8 @@ class HaiRoboticsController
             'errorMsg'=>'波次任务不能为空'
             'errorMsg'=>'波次任务不能为空'
         ];
         ];
         $batchTask=StationTaskBatch::query()->find($request['station_task_batch_id']);
         $batchTask=StationTaskBatch::query()->find($request['station_task_batch_id']);
-        $batchesFailed=$this->stationTaskBatchService->runMany(collect([$batchTask]));//执行波次任务
+        $batchesFailed=$this->stationTaskBatchService->runMany(collect([$batchTask]),
+            $request->input("isCacheShelf") ? 'OUTBIN-CACHE-SHELF' : 'OUTBIN-U-SHAPE-LINE');//执行波次任务
         if($batchesFailed && $batchesFailed->isNotEmpty()){
         if($batchesFailed && $batchesFailed->isNotEmpty()){
             return [
             return [
                 'success'=>false,
                 'success'=>false,

+ 2 - 14
app/Http/Controllers/api/thirdPart/haiq/LightController.php

@@ -3,15 +3,11 @@
 
 
 namespace App\Http\Controllers\api\thirdPart\haiq;
 namespace App\Http\Controllers\api\thirdPart\haiq;
 
 
-
-
-
 use App\Services\CacheShelfService;
 use App\Services\CacheShelfService;
 use App\Services\ForeignHaiRoboticsService;
 use App\Services\ForeignHaiRoboticsService;
 use App\Station;
 use App\Station;
 use App\Traits\TestableInstant;
 use App\Traits\TestableInstant;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
 
 
 class LightController
 class LightController
 {
 {
@@ -20,14 +16,6 @@ class LightController
 
 
     /** @var ForeignHaiRoboticsService $service */
     /** @var ForeignHaiRoboticsService $service */
     private $foreignHaiRoboticsService;
     private $foreignHaiRoboticsService;
-    public function __construct(){
-        $this->foreignHaiRoboticsService=null;
-    }
-
-    public function lightOn($post){
-    }
-    public function lightOff(Request $request){
-    }
 
 
     /**
     /**
      * @param Request $request {"areaCode":"1004","locCode":"HAIB2-02-03","displayInfo":null,"PTLAction":0,"PTLSettings":null}
      * @param Request $request {"areaCode":"1004","locCode":"HAIB2-02-03","displayInfo":null,"PTLAction":0,"PTLSettings":null}
@@ -51,12 +39,12 @@ class LightController
                 }
                 }
                 /** @var CacheShelfService $cacheShelfService */
                 /** @var CacheShelfService $cacheShelfService */
                 $cacheShelfService = app(CacheShelfService::class);
                 $cacheShelfService = app(CacheShelfService::class);
-                $result =   $cacheShelfService->lightOffTask($request['locCode'],$request['PTLAction']);
+                $result =   $cacheShelfService->lightOffTask($request['locCode']);
                 $response['location']=$result['success']??'';
                 $response['location']=$result['success']??'';
                 $response['errMsg']=$result['errMsg']??'';
                 $response['errMsg']=$result['errMsg']??'';
                 return $response;
                 return $response;
             case 'U型线拍灯':
             case 'U型线拍灯':
-//                $this->foreignHaiRoboticsService->uLineLightPat($station);
+//                废弃此入口 U型线拍灯口迁移至 PickStationController:processed
         }
         }
 
 
         return $response;
         return $response;

+ 9 - 0
app/Http/Controllers/api/thirdPart/jianshang/RejectedController.php

@@ -4,6 +4,7 @@
 namespace App\Http\Controllers\api\thirdPart\jianshang;
 namespace App\Http\Controllers\api\thirdPart\jianshang;
 
 
 
 
+use App\Components\ErrorPush;
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
 use App\Logistic;
 use App\Logistic;
 use App\QualityLabel;
 use App\QualityLabel;
@@ -17,6 +18,8 @@ use Zttp\ZttpResponse;
 
 
 class RejectedController extends Controller
 class RejectedController extends Controller
 {
 {
+    use ErrorPush;
+
     function sendRejected($rejected){
     function sendRejected($rejected){
         $amount = $rejected['amount'] ?? '';
         $amount = $rejected['amount'] ?? '';
         $created_at = $rejected['created_at'] ?? '';
         $created_at = $rejected['created_at'] ?? '';
@@ -201,6 +204,12 @@ class RejectedController extends Controller
             $forSign = $str . $timestamp . $nonce . $signKey;
             $forSign = $str . $timestamp . $nonce . $signKey;
             return strtolower(md5($forSign));
             return strtolower(md5($forSign));
         };
         };
+        if (!$data){
+            app('LogService')->log(__METHOD__,'笕尚接口参数异常',json_encode(array($created_at,$fee_collected,$goodses,
+                $logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
+                $sender_mobile,$sender_name)));
+            return false;
+        }
         $timestamp=intval(microtime(true)*1000);
         $timestamp=intval(microtime(true)*1000);
         $nonce=md5(microtime(true));
         $nonce=md5(microtime(true));
         $sign=$sortParamsAndMd5(json_decode($data,true),$timestamp,$nonce,config('api.sign_key_rejected_send_jianshang'));
         $sign=$sortParamsAndMd5(json_decode($data,true),$timestamp,$nonce,config('api.sign_key_rejected_send_jianshang'));

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

@@ -2,11 +2,14 @@
 
 
 namespace App\Http\Middleware;
 namespace App\Http\Middleware;
 
 
+use App\Components\ErrorPush;
 use App\Services\LogService;
 use App\Services\LogService;
 use Closure;
 use Closure;
+use Illuminate\Support\Facades\Auth;
 
 
 class LogPostRequest
 class LogPostRequest
 {
 {
+    use ErrorPush;
     /**
     /**
      * Handle an incoming request.
      * Handle an incoming request.
      *
      *
@@ -16,12 +19,17 @@ class LogPostRequest
      */
      */
     public function handle($request, Closure $next)
     public function handle($request, Closure $next)
     {
     {
-        if($request->method()!='GET'){
-            LogService::log($request->fullUrl(),$request->method(),
-                '请求:'.json_encode($request->all())
-                .'请求头:'.json_encode($request->headers->all())
-            );
+        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");
         }
         }
-        return $next($request);
     }
     }
 }
 }

+ 39 - 0
app/Http/Requests/RequirementRequest.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Http\Requests;
+
+
+class RequirementRequest extends Request
+{
+    public function rules()
+    {
+        switch($this->method())
+        {
+            case 'POST':
+            case 'PUT':
+            case 'PATCH':
+            {
+                return [
+                    'content'       => 'required|min:3',
+                    'title'       => 'required|min:3',
+                    'score' => 'required|numeric',
+                ];
+            }
+            case 'GET':
+            case 'DELETE':
+            default:
+            {
+                return [];
+            }
+        }
+    }
+
+    public function messages()
+    {
+        return [
+            'content.min' => '内容至少为3个字符',
+            'title.min' => '内容至少为3个字符',
+            'score.numeric' => '分数必须为数字',
+        ];
+    }
+}

+ 31 - 0
app/Interfaces/SettlementBillControllerInterface.php

@@ -0,0 +1,31 @@
+<?php
+
+
+namespace App\Interfaces;
+
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+
+interface SettlementBillControllerInterface
+{
+    /**
+     * 首页
+     * @param Request $request
+     * @return mixed
+     */
+    public function index(Request $request);
+
+    /**
+     * 确认账单
+     * @param Request $request
+     * @return RedirectResponse
+     */
+    public function confirmBill(Request $request): RedirectResponse;
+
+    /**
+     * 报表导出
+     * @param Request $request
+     * @return mixed
+     */
+    public function export(Request $request);
+}

+ 32 - 0
app/Interfaces/SettlementBillDetailInterface.php

@@ -0,0 +1,32 @@
+<?php
+
+
+namespace App\Interfaces;
+
+use Illuminate\Database\Eloquent\Builder;
+
+interface SettlementBillDetailInterface
+{
+    /**
+     * @param $owner_id
+     * @param $counting_month
+     * @return Builder
+     */
+    public function getSql($owner_id, $counting_month): Builder;
+
+    /**
+     * @param $type
+     * @return int|mixed
+     */
+    public function switchType($type);
+
+    public function buildExport($details): array;
+
+    /**
+     * @param array $model
+     * @return mixed
+     */
+    public function add(array $model);
+
+    public function getTotalFee($owner_id, $counting_month);
+}

+ 41 - 0
app/Interfaces/SettlementBillReportInterface.php

@@ -0,0 +1,41 @@
+<?php
+
+
+namespace App\Interfaces;
+
+use Illuminate\Database\Eloquent\Builder;
+
+interface SettlementBillReportInterface
+{
+    /**
+     * 生成报表数据
+     * 如果参数$counting_month为空 统计上一个月的
+     * 如果参数$counting_month为2021-01-01 则统计2021-01-01 -- 2021-01-31之间的数据
+     * @param null $counting_month 统计月份,默认统计上个月的 2021-05-01
+     */
+    public function recordReport($counting_month = null);
+
+
+    /**
+     * @param $owner_id
+     * @param $counting_month
+     * @return Builder
+     */
+    public function getSql($owner_id, $counting_month): Builder;
+
+    /**
+     * @param $type
+     * @return int|mixed
+     */
+    public function switchType($type);
+
+    public function buildExport($details): array;
+
+    /**
+     * 确认账单
+     * @param $counting_month
+     * @param $owner_id
+     * @return mixed
+     */
+    public function confirmBill($counting_month, $owner_id);
+}

+ 87 - 12
app/Jobs/CacheShelfTaskJob.php

@@ -2,18 +2,22 @@
 
 
 namespace App\Jobs;
 namespace App\Jobs;
 
 
+use App\Components\ErrorPush;
 use App\Services\ForeignHaiRoboticsService;
 use App\Services\ForeignHaiRoboticsService;
+use App\Station;
 use App\StationTaskMaterialBox;
 use App\StationTaskMaterialBox;
+use App\TaskTransaction;
 use Illuminate\Bus\Queueable;
 use Illuminate\Bus\Queueable;
 use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Foundation\Bus\Dispatchable;
 use Illuminate\Foundation\Bus\Dispatchable;
 use Illuminate\Queue\InteractsWithQueue;
 use Illuminate\Queue\InteractsWithQueue;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
 
 
 class CacheShelfTaskJob implements ShouldQueue
 class CacheShelfTaskJob implements ShouldQueue
 {
 {
-    use Dispatchable, InteractsWithQueue, Queueable;
+    use Dispatchable, InteractsWithQueue, Queueable, ErrorPush;
 
 
     protected $key;
     protected $key;
     protected $count;
     protected $count;
@@ -32,21 +36,92 @@ class CacheShelfTaskJob implements ShouldQueue
      * Execute the job.
      * Execute the job.
      *
      *
      * @return void
      * @return void
+     * @throws
      */
      */
     public function handle()
     public function handle()
     {
     {
         /** @var ForeignHaiRoboticsService $service */
         /** @var ForeignHaiRoboticsService $service */
         $service = app("ForeignHaiRoboticsService");
         $service = app("ForeignHaiRoboticsService");
-        if (!Cache::has($this->key))return;
-        /** @var Collection $task */
-        list($task,$location) = Cache::get($this->key);
-        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)
-            ->where("status","待处理")->update(['status' => $controlSuccess ? '处理中' : '异常']);
-        Cache::forget($this->key);
+        switch ($this->key){
+            case "CACHE_SHELF_AVAILABLE"://出库呼叫
+                DB::beginTransaction();
+                try {
+                    $available = Cache::get($this->key,function (){return [];});
+                    if ($this->count!==count($available))return;
+                    $tasks = TaskTransaction::query()->with("task")
+                        ->where("type","出库")->whereHas("task",function ($query){
+                            $query->where("status","待处理");
+                        })->where("status",3)->lockForUpdate()
+                        ->where("mark",2)->groupBy("task_id")->get(); //检索等待的队列事务来获取对应任务
+                    if (!$tasks->count())return;
+                    $tasks = $tasks->where("task.station_task_batch_id",$tasks[0]->task->station_task_batch_id);//仅处理同波次
+                    if ($tasks->count()>count($available))$tasks = $tasks->slice(0,count($available));//事务过多切割部分处理
+                    $toLocation = collect();
+                    $task = collect();
+                    $availableTemp = array_keys($available);
+                    $map = app("StationService")->getStationMapping($availableTemp);//获取库位映射信息
+                    $updateTask = [["id","station_id","updated_at"]];
+                    $updateTransaction = [["id","to_station_id","status","updated_at"]];
+                    $time = date("Y-m-d H:i:s");
+                    foreach ($tasks as $index=>$obj){
+                        $loc = $availableTemp[$index];
+                        $toLocation->push($loc);
+                        $obj->task->station_id = $map[$loc];
+                        $task->push($obj->task);
+                        unset($available[$loc]);
+                        $updateTask[] = ["id"=>$obj->task->id,"station_id"=>$map[$loc],"updated_at"=>$time];
+                        $updateTransaction[] = ["id"=>$obj->id,"to_station_id"=>$map[$loc],"status"=>0,"updated_at"=>$time];
+                    }
+                    app("BatchUpdateService")->batchUpdate("station_task_material_boxes",$updateTask);
+                    app("BatchUpdateService")->batchUpdate("task_transactions",$updateTransaction);
+                    $result = $service->fetchGroup_multiLocation($toLocation,$task,$tasks[0]->station_task_batch_id,'立架出至缓存架',20);
+                    if ($result){
+                        Cache::forever($this->key,$available);
+                        foreach ($toLocation as $value){
+                            app("CacheShelfService")->lightUp($value,'3','2');
+                            Cache::forever("CACHE_SHELF_OCCUPANCY_{$map[$value]}",true);
+                        }
+                        app("StationService")->locationOccupyMulti($toLocation->toArray());
+                        DB::commit();
+                    }else{
+                        DB::rollBack();
+                        $this->push(__METHOD__."->".__LINE__,"出库队列执行失败","库位信息:".json_encode($toLocation)."  任务信息:".json_encode($task));
+                    }
+                }catch (\Exception $e){
+                    DB::rollBack();
+                    $this->push(__METHOD__."->".__LINE__,"出库队列执行错误",$e->getMessage());
+                }
+                break;
+            default://入库呼叫
+                if (!Cache::has($this->key))return;
+                /** @var Collection $task */
+                list($task,$location) = Cache::get($this->key);
+                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)
+                    ->where("status","待处理")->update(['status' => $controlSuccess ? '处理中' : '异常']);
+                Cache::forget($this->key);
+                if ($controlSuccess)$this->materialBoxMappingCacheShelf($task,$location);
+        }
+    }
+
+    /**
+     * 料箱映射缓存架,因为建立的入立架任务源库位是立库,无法获取真实源库位,所以在此拿到映射库位
+     * 在料箱被取走时通过任务料箱号获取对应库位,来标记该缓存架库位可以被执行任务了 StationTaskMaterialBoxService:markHasTaken
+     * 出库会启用库位占用逻辑  入库分为:人工入库与系统自动入库 人工控制入库由人工自己辨识库位可用度,而系统入库只能通过此映射来拿到可用库位信息
+     *
+     * @param Collection $task
+     * @param Collection $location
+     *
+     * @return void
+     */
+    public function materialBoxMappingCacheShelf(Collection $task,Collection $location)
+    {
+        $map = Cache::get("CACHE_SHELF_MAPPING",function (){return [];});
+        foreach ($task as $key=>$obj)$map[$obj->material_box_id] = $location[$key];
+        Cache::forever("CACHE_SHELF_MAPPING",$map);
     }
     }
 }
 }

+ 52 - 0
app/Jobs/SettlementBillCountingTask.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Jobs;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+/**
+ * 生成结算账单统计数据
+ * 每月初始执行
+ * 统计上月的账单数据
+ * Class SettlementBillCountingTask
+ * @package App\Jobs
+ */
+class SettlementBillCountingTask implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    //货主
+    private $owner_id;
+    //统计月份
+    private $counting_month;
+
+    /**
+     * SettlementBillCountingTask constructor.
+     * @param $owner_id
+     * @param $counting_month
+     */
+    public function __construct($owner_id, $counting_month)
+    {
+        $this->owner_id = $owner_id;
+        $this->counting_month = $counting_month;
+    }
+
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        if (is_null($this->owner_id)&&is_null($this->counting_month)) {//未指定统计的参数
+        } else {
+            //清除历史统计记录
+
+        }
+    }
+}

+ 66 - 0
app/Jobs/SettlementBillReportTask.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Services\OwnerFeeTotalService;
+use App\Services\OwnerLogisticFeeReportService;
+use App\Services\OwnerStoreFeeReportService;
+use App\Services\OwnerStoreOutFeeReportService;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+/**
+ * 快递 出库 入库 统计报表生成任务
+ * Class SettlementBillReportTask
+ * @package App\Jobs
+ */
+class SettlementBillReportTask implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    public $timeout = 120;
+
+    public $maxExceptions = 3;
+
+    public $tries = 2;
+    /**
+     * Create a new job instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        //快递
+        /** @var OwnerLogisticFeeReportService $expressFeeReportService */
+        $expressFeeReportService = app('OwnerLogisticFeeReportService');
+        $expressFeeReportService->recordReport();
+
+        //入库
+        /** @var OwnerStoreFeeReportService $storeFeeReportService */
+        $storeFeeReportService = app('OwnerStoreFeeReportService');
+        $storeFeeReportService->recordReport();
+
+        //出库
+        /** @var OwnerStoreOutFeeReportService $storeOutFeeReportService */
+        $storeOutFeeReportService = app('OwnerStoreOutFeeReportService');
+        $storeOutFeeReportService->recordReport();
+
+        //总账单
+        /** @var OwnerFeeTotalService $feeTotal */
+        $feeTotal = app('OwnerFeeTotalService');
+        $feeTotal->record();
+    }
+}

+ 37 - 0
app/Listeners/SettlementBillCreateListener.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Listeners;
+
+use App\Events\SettlementBillCreateEvent;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Queue\InteractsWithQueue;
+
+class SettlementBillCreateListener implements ShouldQueue
+{
+
+    /**
+     * Create the event listener.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Handle the event.
+     *
+     * @param SettlementBillCreateEvent $event
+     * @return void
+     */
+    public function handle(SettlementBillCreateEvent $event)
+    {
+        $createData = $event->createData;
+        /** @var Model $modelName */
+        $modelName = $event->modelName;
+        $modelName::uDelete($createData);
+        $modelName::query()->updateOrCreate($createData);
+    }
+}

+ 14 - 1
app/Logistic.php

@@ -17,8 +17,13 @@ class Logistic extends Model
     use ModelLogChanging;
     use ModelLogChanging;
     use SoftDeletes;
     use SoftDeletes;
     use ModelTimeFormat;
     use ModelTimeFormat;
-    protected $fillable = ['name','code',"type","mobile","remark","delivery_fee","is_bunched","english_name",'belong_company'];
+    protected $fillable = ['name','code',"type","mobile","remark","delivery_fee","is_bunched","english_name",'belong_company',"tag"];
 
 
+    const TAGS=[
+        0 => "专线",
+        1 => "直发车",
+        2 => "德邦",
+    ];
 
 
     static function nameById($id){
     static function nameById($id){
         $logistic=Logistic::where('id',$id)->first();
         $logistic=Logistic::where('id',$id)->first();
@@ -29,4 +34,12 @@ class Logistic extends Model
     {
     {
         return $this->belongsToMany(OwnerPriceExpress::class,"owner_price_express_logistic","logistic_id","owner_price_express_id");
         return $this->belongsToMany(OwnerPriceExpress::class,"owner_price_express_logistic","logistic_id","owner_price_express_id");
     }
     }
+
+    public function getTagAttribute($value):string
+    {
+        if ($value==="" || $value===null)return "";
+        $tag = explode(",",$value);
+        foreach ($tag as &$t)$t = self::TAGS[$t];
+        return implode(",",$tag);
+    }
 }
 }

+ 5 - 0
app/MaterialBox.php

@@ -5,6 +5,7 @@ namespace App;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
 
 
 use App\Traits\ModelLogChanging;
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasOne;
 
 
 class MaterialBox extends Model
 class MaterialBox extends Model
 {
 {
@@ -33,6 +34,10 @@ class MaterialBox extends Model
         parent::__construct($attributes);
         parent::__construct($attributes);
     }
     }
 
 
+    public function station():HasOne
+    {
+        return $this->hasOne(Station::class);
+    }
     public function getStatusAttribute($value)
     public function getStatusAttribute($value)
     {
     {
         if(!$value)return '';
         if(!$value)return '';

+ 22 - 0
app/MaterialBoxCommodity.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class MaterialBoxCommodity extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable=[
+        "material_box_id","commodity_id","amount"
+    ];
+
+    public function materialBox():BelongsTo
+    {
+        return $this->belongsTo(MaterialBox::class);
+    }
+}

+ 6 - 0
app/MaterialBoxModel.php

@@ -5,6 +5,7 @@ namespace App;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
 
 
 use App\Traits\ModelLogChanging;
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasOne;
 
 
 class MaterialBoxModel extends Model
 class MaterialBoxModel extends Model
 {
 {
@@ -13,4 +14,9 @@ class MaterialBoxModel extends Model
     protected $fillable=[
     protected $fillable=[
         "code","description","maximum_kind"
         "code","description","maximum_kind"
     ];
     ];
+
+    public function commodity():HasOne
+    {
+        return $this->hasOne(CommodityMaterialBoxModel::class);
+    }
 }
 }

+ 21 - 0
app/OracleBasLotId.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelLogChanging;
+
+/**
+ * DB:      FLUX/WMS_USER
+ * TABLE:   BAS_LOTID
+ * EXPLAIN: 批次属性规则表
+ */
+class OracleBasLotId extends Model
+{
+    use ModelTimeFormat;
+    use ModelLogChanging;
+
+    protected $connection="oracle";
+    protected $table="BAS_LOTID";
+}

+ 5 - 1
app/OracleBasSKU.php

@@ -9,7 +9,6 @@ use Illuminate\Database\Eloquent\Model;
  * EXPLAIN: 商品
  * EXPLAIN: 商品
  */
  */
 use App\Traits\ModelTimeFormat;
 use App\Traits\ModelTimeFormat;
-
 use App\Traits\ModelLogChanging;
 use App\Traits\ModelLogChanging;
 
 
 class OracleBasSKU extends Model
 class OracleBasSKU extends Model
@@ -26,4 +25,9 @@ class OracleBasSKU extends Model
      *         Descr_C 商品名称
      *         Descr_C 商品名称
      *
      *
      * */
      * */
+    public function lotId()
+    {
+        return $this->hasOne(OracleBasLotId::class,'lotid','lotid')
+            ->select('lotid','lotkey01','lotkey02','lotkey03','lotkey04','lotkey05','lotkey08');
+    }
 }
 }

+ 0 - 1
app/OracleDOCASNHeader.php

@@ -4,7 +4,6 @@ namespace App;
 
 
 use App\Traits\ModelTimeFormat;
 use App\Traits\ModelTimeFormat;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
-
 use App\Traits\ModelLogChanging;
 use App\Traits\ModelLogChanging;
 
 
 class OracleDOCASNHeader extends Model
 class OracleDOCASNHeader extends Model

+ 3 - 1
app/Owner.php

@@ -4,6 +4,7 @@ namespace App;
 
 
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Auth;
 
 
@@ -36,7 +37,8 @@ class Owner extends Model
         "user_workgroup_id",    //仓库小组(工作组)
         "user_workgroup_id",    //仓库小组(工作组)
         "relevance",            //关联模型的JSON数组
         "relevance",            //关联模型的JSON数组
         'subjection',           //主体公司
         'subjection',           //主体公司
-        'is_tax_exist'          //是否必填税率
+        'is_tax_exist',         //是否必填税率
+        'model_sequence'        //调箱序列(优先级匹配)
     ];
     ];
     //relevance说明 0:仓储 1:作业 2:快递 3:物流 4:直发 5:系统 存储示例:["0","1"]存在仓储与作业计费
     //relevance说明 0:仓储 1:作业 2:快递 3:物流 4:直发 5:系统 存储示例:["0","1"]存在仓储与作业计费
     protected $casts = [
     protected $casts = [

+ 10 - 9
app/OwnerBillReportArchive.php

@@ -27,15 +27,16 @@ class OwnerBillReportArchive extends Model
         'type' => [
         'type' => [
             '' => 0,
             '' => 0,
             '仓储费' => 1,
             '仓储费' => 1,
-            '快递费-明细' => 2,
-            '快递费-合计' => 3,
-            '入库费' => 4,
-            '出库费' => 5,
-            '物流费' => 6,
-            '包材费' => 7,
-            '加工费' => 8,
-            '杂项' => 9,
-            '卸货费' => 10,
+            '快递费-合计' => 2,
+            '入库费-合计' => 3,
+            '出库费-合计' => 4,
+            '物流费' => 5,
+            '包材费' => 6,
+            '加工费' => 7,
+            '杂项费' => 8,
+            '卸货费' => 9,
+            '总费用' => 10,
+            '理赔费' => 11,
         ],
         ],
     ];
     ];
 
 

+ 12 - 2
app/OwnerFeeDetail.php

@@ -2,12 +2,12 @@
 
 
 namespace App;
 namespace App;
 
 
-use App\Services\ProcessMethodService;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
 
 
-use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Database\Eloquent\Relations\HasOne;
 use Illuminate\Database\Eloquent\Relations\HasOne;
+use Illuminate\Database\Eloquent\Relations\MorphTo;
 
 
 class OwnerFeeDetail extends Model
 class OwnerFeeDetail extends Model
 {
 {
@@ -77,4 +77,14 @@ class OwnerFeeDetail extends Model
     {
     {
         return $this->hasOne(OwnerLogisticFeeDetail::class,'logistic_bill','logistic_bill');
         return $this->hasOne(OwnerLogisticFeeDetail::class,'logistic_bill','logistic_bill');
     }
     }
+
+    public function ownerPriceOperation(): BelongsTo
+    {
+        return $this->belongsTo(OwnerPriceOperation::class);
+    }
+
+    public function process()
+    {
+        return $this->hasOne('App\Process','id','outer_id');
+    }
 }
 }

+ 45 - 0
app/OwnerFeeTotal.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class OwnerFeeTotal extends Model
+{
+    use ModelLogChanging;
+
+    public $fillable = [
+        'owner_id',//货主
+        'counting_month',//结算月
+        'discount_fee',//优惠费
+        'discount_remark',//优惠备注
+        'information',//仓储,入库出库费
+        'fee',//总费用
+        'logistic_fee',//物流费
+        'logistic_tax_fee',//物流税费
+        'express_fee',//快递费
+        'express_tax_fee',//快递税费
+        'process_fee',//加工费
+        'process_tax_fee',//加工税费
+        'system_fee',//系统使用费
+        'system_tax_fee',//系统使用税费
+        'sundry_information',//杂项费
+        'tax_rate',//税率
+        'indemnity_fee',//理赔费
+        'packing_material_fee',//包材费
+        'unload_fee',//卸货费
+    ];
+
+    public $casts = [
+        'information'=>'array',
+        'sundry_information'=>'array',
+    ];
+
+    public function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+}

+ 31 - 2
app/OwnerLogisticFeeDetail.php

@@ -12,7 +12,19 @@ class OwnerLogisticFeeDetail extends Model
 {
 {
     use ModelLogChanging;
     use ModelLogChanging;
 
 
-    public $fillable = ['owner_fee_detail_id', 'logistic_bill', 'initial_weight', 'initial_weight_price', 'additional_weight', 'additional_price','logistic_id','owner_id','additional_weigh_weight'];
+    public $fillable = [
+        'owner_fee_detail_id', //
+        'logistic_bill',//快递单号
+        'initial_weight',//首重
+        'initial_weight_price',//首重价格
+        'additional_weight',//续重
+        'additional_price',//续重价格
+        'logistic_id',//承运商
+        'owner_id',//货主
+        'additional_weigh_weight',//续重重量
+        'tax_fee',//税费
+        'fee'//费用
+    ];
 
 
     public function ownerFeeDetail(): BelongsTo
     public function ownerFeeDetail(): BelongsTo
     {
     {
@@ -22,11 +34,28 @@ class OwnerLogisticFeeDetail extends Model
 
 
     public function ownerFeeDetailLogistic(): BelongsTo
     public function ownerFeeDetailLogistic(): BelongsTo
     {
     {
-        return $this->belongsTo(OwnerFeeDetailLogistic::class,'logistic_bill', 'logistic_bill');
+        return $this->belongsTo(OwnerFeeDetailLogistic::class, 'logistic_bill', 'logistic_bill');
     }
     }
 
 
     public function logistic(): BelongsTo
     public function logistic(): BelongsTo
     {
     {
         return $this->belongsTo(Logistic::class);
         return $this->belongsTo(Logistic::class);
     }
     }
+
+    /**
+     * 根据参数条件删除
+     * @param $data
+     */
+    public static function uDelete($data)
+    {
+        self::query()
+            ->where('owner_fee_detail_id', $data['owner_fee_detail_id'])
+            ->where('logistic_bill', $data['logistic_bill'])
+            ->where('initial_weight', $data['initial_weight'])
+            ->where('additional_weight', $data['additional_weight'])
+            ->where('logistic_id', $data['logistic_id'])
+            ->where('owner_id', $data['owner_id'])
+            ->where('additional_weigh_weight', $data['additional_weigh_weight'])
+            ->delete();
+    }
 }
 }

+ 15 - 1
app/OwnerLogisticFeeReport.php

@@ -11,7 +11,21 @@ class OwnerLogisticFeeReport extends Model
 {
 {
     use ModelLogChanging;
     use ModelLogChanging;
 
 
-    public $fillable = ['owner_logistic_sum_fee_report_id', 'logistic_id', 'province', 'counted_date', 'initial_weight', 'initial_weight_price', 'initial_amount', 'additional_weight', 'additional_price', 'additional_amount', 'fee','owner_id'];
+    public $fillable = [
+        'owner_logistic_sum_fee_report_id',//
+        'logistic_id',//承运商
+        'province', //省份
+        'counted_date',//统计月份
+        'initial_weight',//首重
+        'initial_weight_price',//首重价格
+        'initial_amount', //数量
+        'additional_weight', //续重
+        'additional_price', //续重价格
+        'additional_amount',//续重数量
+        'fee',//费用
+        'tax_fee',//税费
+        'owner_id'//货主
+    ];
     public $timestamps = false;
     public $timestamps = false;
 
 
     public function logistic(): BelongsTo
     public function logistic(): BelongsTo

+ 3 - 0
app/OwnerMaterial.php

@@ -38,6 +38,9 @@ class OwnerMaterial extends Model
     public function getSpecificationAttribute($value){
     public function getSpecificationAttribute($value){
         return str_replace(array("\r\n","\n","\r","\"","&quot;"),' ',$value);
         return str_replace(array("\r\n","\n","\r","\"","&quot;"),' ',$value);
     }
     }
+    public function getSpecialAttribute($value){
+        return str_replace(array("\r\n","\n","\r","\"","&quot;"),' ',$value);
+    }
 
 
     public function scopeFilter($query,$filters)
     public function scopeFilter($query,$filters)
     {
     {

+ 1 - 1
app/OwnerPriceOperationItem.php

@@ -28,7 +28,7 @@ class OwnerPriceOperationItem extends Model
 
 
     public function unit()
     public function unit()
     {   //单位
     {   //单位
-        return $this->hasOne(Unit::class,"id","unit_id");
+        return $this->belongsTo(Unit::class);
     }
     }
     public function ownerPriceOperation()
     public function ownerPriceOperation()
     {   //作业计费
     {   //作业计费

+ 74 - 0
app/OwnerStoreFeeDetail.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class OwnerStoreFeeDetail extends Model
+{
+    use ModelLogChanging;
+
+    public $fillable = [
+        'owner_fee_detail_id',
+        'unit_id',
+        'unit_price', //单价
+        'amount', //数量
+        'owner_id', //货主
+        'fee',//费用
+        'commodity_id',
+        'packing_material_fee',//包材费
+        'tax_fee',//税费
+        'sku',//sku
+        'barcode',//条码
+        'work_name',//作业名称
+        'asn_code',//asn号
+    ];
+
+    public function ownerFeeDetail(): BelongsTo
+    {
+        return $this->belongsTo(OwnerFeeDetail::class);
+
+    }
+
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class);
+    }
+
+    public function getPriceAttribute(): string
+    {
+        return $this->unit_price . '/' . $this->unit->name;
+    }
+
+    public function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+
+    public function commodity(): BelongsTo
+    {
+        return $this->belongsTo(Commodity::class);
+    }
+
+
+    /**
+     * 根据参数条件删除
+     * @param $data
+     */
+    public static function uDelete($data)
+    {
+        self::query()
+            ->where('owner_fee_detail_id', $data['owner_fee_detail_id'])
+            ->where('unit_id', $data['unit_id'])
+            ->where('owner_id', $data['owner_id'])
+            ->where('commodity_id', $data['commodity_id'])
+            ->where('sku', $data['sku'])
+            ->where('barcode', $data['barcode'])
+            ->where('work_name', $data['work_name'])
+            ->where('asn_code', $data['asn_code'])
+            ->delete();
+    }
+}

+ 46 - 0
app/OwnerStoreFeeReport.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class OwnerStoreFeeReport extends Model
+{
+    use ModelLogChanging;
+
+    public $fillable = [
+        'owner_bill_report_id',
+        'owner_id',
+        'counting_month', //统计月份
+        'unit_id', //单位
+        'unit_price', //单价
+        'amount', //数量
+        'fee',//费用
+        'work_name',//作业名称
+    ];
+
+    public $timestamps = false;
+
+    public function ownerBillReport(): BelongsTo
+    {
+        return $this->belongsTo(OwnerBillReport::class);
+    }
+
+    public function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class);
+    }
+
+    public function getPriceAttribute(): string
+    {
+        return $this->unit_price . '/' . $this->unit->name;
+    }
+}

+ 69 - 0
app/OwnerStoreOutFeeDetail.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class OwnerStoreOutFeeDetail extends Model
+{
+    use ModelLogChanging;
+
+    public $fillable = [
+        'owner_fee_detail_id',//
+        'commodity_id',//
+        'owner_id',//
+        'source_bill', // 上游单号
+        'unit_price', //价格
+        'unit_id', //
+        'amount',//数量
+        'step',//阶梯
+        'price_remark',//价格描述
+        'tax_fee',//税费
+        'sku',//商家编码
+        'packingMaterialFee',//耗材费
+        'barcode',//商品条码
+        'work_name',//作业名称
+        'fee',//费用
+    ];
+
+    public function ownerFeeDetail(): BelongsTo
+    {
+        return $this->belongsTo(OwnerFeeDetail::class);
+    }
+
+    public function commodity(): BelongsTo
+    {
+        return $this->belongsTo(Commodity::class);
+    }
+
+    public function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class);
+    }
+
+    /**
+     * 根据参数条件删除
+     * @param $data
+     */
+    public static function uDelete($data)
+    {
+        self::query()
+            ->where('owner_fee_detail_id',$data['owner_fee_detail_id'])
+            ->where('commodity_id',$data['commodity_id'])
+            ->where('owner_id',$data['owner_id'])
+            ->where('source_bill',$data['source_bill'])
+            ->where('unit_id',$data['unit_id'])
+            ->where('sku',$data['sku'])
+            ->where('barcode',$data['barcode'])
+            ->where('work_name',$data['work_name'])
+            ->delete();
+    }
+}

+ 42 - 0
app/OwnerStoreOutFeeReport.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class OwnerStoreOutFeeReport extends Model
+{
+    use ModelLogChanging;
+
+    public $fillable = [
+        'owner_bill_report_id',
+        'counting_month',
+        'step', //阶梯
+        'unit_id',
+        'unit_price',//单价
+        'amount', //数量
+        'owner_id',
+        'work_name',//作业名称
+        'fee',//费用
+    ];
+
+    public $timestamps = false;
+
+    public function ownerBillReport(): BelongsTo
+    {
+        return $this->belongsTo(OwnerBillReport::class);
+    }
+
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class);
+    }
+
+    public function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+}

+ 49 - 0
app/OwnerWayBillFeeDetail.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class OwnerWayBillFeeDetail extends Model
+{
+    use ModelLogChanging;
+
+    public $fillable = [
+        'owner_fee_detail_id',
+        'waybill_id',
+        'util_id',
+        'step',//计数区间
+        'fuel_fee',//燃油附加费
+        'service_fee',//信息费
+        'originate_fee',//起始计费
+        'originate_count',//起始计数
+        'price',//单价
+        'delivery_fee'//送货费
+    ];
+
+    public function ownerFeeDetail()
+    {
+        return $this->belongsTo(OwnerFeeDetail::class);
+    }
+
+    public function waybill()
+    {
+        return $this->belongsTo(Waybill::class);
+    }
+
+    public function unit()
+    {
+        return $this->belongsTo(Unit::class);
+    }
+
+    /**
+     * 根据参数条件删除
+     * @param $data
+     */
+    public static function uDelete($data)
+    {
+
+    }
+}

+ 37 - 0
app/Policies/RequirementPolicy.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Policies;
+
+use App\User;
+use Illuminate\Auth\Access\HandlesAuthorization;
+
+class RequirementPolicy
+{
+    use HandlesAuthorization;
+
+    /**
+     * Create a new policy instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    public function update(User $user, \App\Requirement $requirement)
+    {
+        // return $owner_sundry_fee_detail->user_id == $user->id;
+        return true;
+    }
+
+    public function destroy(User $user, \App\Requirement $requirement)
+    {
+        return $requirement->status != '已完成';
+    }
+
+    public function begin(User $user ,\App\Requirement $requirement)
+    {
+        return $requirement->status == '已发布';
+    }
+}

+ 32 - 4
app/Providers/AppServiceProvider.php

@@ -4,10 +4,6 @@ namespace App\Providers;
 
 
 use App\Authority;
 use App\Authority;
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
-use App\Jobs\LogisticSFSync;
-use App\Jobs\LogisticYDSync;
-use App\Jobs\LogisticYTOSync;
-use App\Jobs\LogisticZopSync;
 use App\Menu;
 use App\Menu;
 use App\Observers\AuthorityObserver;
 use App\Observers\AuthorityObserver;
 use App\Observers\MenuObserver;
 use App\Observers\MenuObserver;
@@ -148,9 +144,25 @@ use App\Services\OwnerLogisticFeeReportService;
 use App\Services\LogisticSyncRecordService;
 use App\Services\LogisticSyncRecordService;
 use App\Services\OwnerBillReportArchiveService;
 use App\Services\OwnerBillReportArchiveService;
 use App\Services\SettlementBillsAreaFeeService;
 use App\Services\SettlementBillsAreaFeeService;
+use App\Services\OwnerStoreFeeDetailService;
+use App\Services\OwnerStoreFeeReportService;
+use App\Services\OwnerStoreOutFeeDetailService;
+use App\Services\OwnerStoreOutFeeReportService;
+use App\Services\OwnerSundryFeeDetailService;
+use App\Services\OwnerProcurementSettlementBillService;
+use App\Services\OwnerWaybillSettlementBillService;
+use App\Services\OwnerProcessSettlementBillService;
+use App\Services\OwnerDischargeTaskSettlementBillService;
+use App\Services\OwnerFeeTotalService;
+use App\Services\OwnerWayBillFeeDetailService;
+use App\Services\SettlementIndemnityFeeService;
 use App\Services\DbOpenService;
 use App\Services\DbOpenService;
 use App\Services\DeliveryTypeService;
 use App\Services\DeliveryTypeService;
 use App\Services\ErrorPushService;
 use App\Services\ErrorPushService;
+use App\Services\MaterialBoxModelService;
+use App\Services\HandInStorageService;
+use App\Services\RequirementService;
+use App\Services\RequirementUserService;
 
 
 class AppServiceProvider extends ServiceProvider
 class AppServiceProvider extends ServiceProvider
 {
 {
@@ -246,6 +258,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('ForeignHaiRoboticsService',ForeignHaiRoboticsService::class);
         app()->singleton('ForeignHaiRoboticsService',ForeignHaiRoboticsService::class);
         app()->singleton('ForeignZhenCangService',ForeignZhenCangService::class);
         app()->singleton('ForeignZhenCangService',ForeignZhenCangService::class);
         app()->singleton('GoodScanWeightService',GoodScanWeightService::class);
         app()->singleton('GoodScanWeightService',GoodScanWeightService::class);
+        app()->singleton('HandInStorageService',HandInStorageService::class);
         app()->singleton('HaoChuangWeightService',HaoChuangWeightService::class);
         app()->singleton('HaoChuangWeightService',HaoChuangWeightService::class);
         app()->singleton('HengLiWeightService',HengLiWeightService::class);
         app()->singleton('HengLiWeightService',HengLiWeightService::class);
         app()->singleton('InventoryAccountMissionService', InventoryAccountMissionService::class);
         app()->singleton('InventoryAccountMissionService', InventoryAccountMissionService::class);
@@ -264,6 +277,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('LogisticYTOService', LogisticYTOService::class);
         app()->singleton('LogisticYTOService', LogisticYTOService::class);
         app()->singleton('LogisticZopService', LogisticZopService::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('MaterialBoxService', MaterialBoxService::class);
         app()->singleton('MenuService',MenuService::class);
         app()->singleton('MenuService',MenuService::class);
         app()->singleton('NewOrderCountingRecordService',NewOrderCountingRecordService::class);
         app()->singleton('NewOrderCountingRecordService',NewOrderCountingRecordService::class);
@@ -292,7 +306,9 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OwnerAreaReportService', OwnerAreaReportService::class);
         app()->singleton('OwnerAreaReportService', OwnerAreaReportService::class);
         app()->singleton('OwnerBillReportArchiveService',OwnerBillReportArchiveService::class);
         app()->singleton('OwnerBillReportArchiveService',OwnerBillReportArchiveService::class);
         app()->singleton('OwnerBillReportService', OwnerBillReportService::class);
         app()->singleton('OwnerBillReportService', OwnerBillReportService::class);
+        app()->singleton('OwnerDischargeTaskSettlementBillService',OwnerDischargeTaskSettlementBillService::class);
         app()->singleton('OwnerFeeDetailService', OwnerFeeDetailService::class);
         app()->singleton('OwnerFeeDetailService', OwnerFeeDetailService::class);
+        app()->singleton('OwnerFeeTotalService',OwnerFeeTotalService::class);
         app()->singleton('OwnerLogisticFeeDetailService',OwnerLogisticFeeDetailService::class);
         app()->singleton('OwnerLogisticFeeDetailService',OwnerLogisticFeeDetailService::class);
         app()->singleton('OwnerLogisticFeeReportService',OwnerLogisticFeeReportService::class);
         app()->singleton('OwnerLogisticFeeReportService',OwnerLogisticFeeReportService::class);
         app()->singleton('OwnerMaterialService', OwnerMaterialService::class);
         app()->singleton('OwnerMaterialService', OwnerMaterialService::class);
@@ -302,9 +318,18 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OwnerPriceLogisticService', OwnerPriceLogisticService::class);
         app()->singleton('OwnerPriceLogisticService', OwnerPriceLogisticService::class);
         app()->singleton('OwnerPriceOperationItemService', OwnerPriceOperationItemService::class);
         app()->singleton('OwnerPriceOperationItemService', OwnerPriceOperationItemService::class);
         app()->singleton('OwnerPriceOperationService', OwnerPriceOperationService::class);
         app()->singleton('OwnerPriceOperationService', OwnerPriceOperationService::class);
+        app()->singleton('OwnerProcessSettlementBillService',OwnerProcessSettlementBillService::class);
+        app()->singleton('OwnerProcurementSettlementBillService',OwnerProcurementSettlementBillService::class);
         app()->singleton('OwnerReportService', OwnerReportService::class);
         app()->singleton('OwnerReportService', OwnerReportService::class);
         app()->singleton('OwnerService', OwnerService::class);
         app()->singleton('OwnerService', OwnerService::class);
         app()->singleton('OwnerStoragePriceModelService', OwnerStoragePriceModelService::class);
         app()->singleton('OwnerStoragePriceModelService', OwnerStoragePriceModelService::class);
+        app()->singleton('OwnerStoreFeeDetailService',OwnerStoreFeeDetailService::class);
+        app()->singleton('OwnerStoreFeeReportService',OwnerStoreFeeReportService::class);
+        app()->singleton('OwnerStoreOutFeeDetailService',OwnerStoreOutFeeDetailService::class);
+        app()->singleton('OwnerStoreOutFeeReportService',OwnerStoreOutFeeReportService::class);
+        app()->singleton('OwnerSundryFeeDetailService',OwnerSundryFeeDetailService::class);
+        app()->singleton('OwnerWayBillFeeDetailService',OwnerWayBillFeeDetailService::class);
+        app()->singleton('OwnerWaybillSettlementBillService',OwnerWaybillSettlementBillService::class);
         app()->singleton('PackageService', PackageService::class);
         app()->singleton('PackageService', PackageService::class);
         app()->singleton('PackageStatisticsService', PackageStatisticsService::class);
         app()->singleton('PackageStatisticsService', PackageStatisticsService::class);
         app()->singleton('PrintPartService',PrintPartService::class);
         app()->singleton('PrintPartService',PrintPartService::class);
@@ -322,8 +347,11 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('RejectedBillItemService', RejectedBillItemService::class);
         app()->singleton('RejectedBillItemService', RejectedBillItemService::class);
         app()->singleton('RejectedBillService', RejectedBillService::class);
         app()->singleton('RejectedBillService', RejectedBillService::class);
         app()->singleton('RejectedService', RejectedService::class);
         app()->singleton('RejectedService', RejectedService::class);
+        app()->singleton('RequirementService',RequirementService::class);
+        app()->singleton('RequirementUserService',RequirementUserService::class);
         app()->singleton('RoleService',RoleService::class);
         app()->singleton('RoleService',RoleService::class);
         app()->singleton('SettlementBillsAreaFeeService',SettlementBillsAreaFeeService::class);
         app()->singleton('SettlementBillsAreaFeeService',SettlementBillsAreaFeeService::class);
+        app()->singleton('SettlementIndemnityFeeService',SettlementIndemnityFeeService::class);
         app()->singleton('ShopService', ShopService::class);
         app()->singleton('ShopService', ShopService::class);
         app()->singleton('StationCacheShelfGridService', StationCacheShelfGridService::class);
         app()->singleton('StationCacheShelfGridService', StationCacheShelfGridService::class);
         app()->singleton('StationRuleBatchService', StationRuleBatchService::class);
         app()->singleton('StationRuleBatchService', StationRuleBatchService::class);

+ 1 - 0
app/Providers/AuthServiceProvider.php

@@ -23,6 +23,7 @@ class AuthServiceProvider extends ServiceProvider
      */
      */
     protected $policies = [
     protected $policies = [
 		 \App\OwnerSundryFeeDetail::class => \App\Policies\OwnerSundryFeeDetailPolicy::class,
 		 \App\OwnerSundryFeeDetail::class => \App\Policies\OwnerSundryFeeDetailPolicy::class,
+		 \App\Requirement::class => \App\Policies\RequirementPolicy::class,
         // 'App\Model' => 'App\Policies\ModelPolicy',
         // 'App\Model' => 'App\Policies\ModelPolicy',
         CustomerLog::class => CustomerLogPolice::class,
         CustomerLog::class => CustomerLogPolice::class,
 
 

+ 3 - 0
app/Providers/EventServiceProvider.php

@@ -49,6 +49,9 @@ class EventServiceProvider extends ServiceProvider
         'App\Events\UpdateOrderPackageExceptionListenerEvent' => [//order_packages的数据的异常数据变更时
         'App\Events\UpdateOrderPackageExceptionListenerEvent' => [//order_packages的数据的异常数据变更时
             'App\Listeners\UpdateOrderPackageExceptionTypeCountingRecordListener',//更新OrderPackageExceptionTypeCountingRecord的统计信息
             'App\Listeners\UpdateOrderPackageExceptionTypeCountingRecordListener',//更新OrderPackageExceptionTypeCountingRecord的统计信息
         ],
         ],
+        'App\Events\SettlementBillCreateEvent' => [
+            'App\Listeners\SettlementBillCreateListener'
+        ],
     ];
     ];
 
 
     /**
     /**

+ 79 - 0
app/Requirement.php

@@ -0,0 +1,79 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
+
+class Requirement extends Model
+{
+    use ModelLogChanging;
+
+    use \App\Traits\ModelTimeFormat;
+
+    use \Illuminate\Database\Eloquent\SoftDeletes;
+
+    //
+    public $fillable = [
+        'user_id',//状态
+        'content', //内容
+        'title', //标题
+        'score', //分数
+        'status',//状态
+        'began_at',//开始时间
+        'finished_at',//完成时间
+    ];
+
+    public $dates = [
+        'began_at',//开始时间
+        'finished_at',//完成时间
+    ];
+
+    static public $enums=[
+        'status'=>[
+            ''=>0,
+            '已发布'=>1,
+            '已开始'=>2,
+            '已完成'=>3,
+        ],
+    ];
+    function __construct(array $attributes = [])
+    {
+        foreach (self::$enums as &$enum) {
+            $enum=$enum+array_flip($enum);
+        }
+        parent::__construct($attributes);
+    }
+
+    public function getStatusAttribute($value)
+    {
+        if(!$value)return '';
+        return self::$enums['status'][$value];
+    }
+    public function setStatusAttribute($value)
+    {
+        if(!$value)return 0;
+        $this->attributes['status']=self::$enums['status'][$value];
+    }
+
+
+    public function creator(): BelongsTo
+    {
+        return $this->belongsTo(User::class,'user_id','id');
+    }
+
+    public function workers(): BelongsToMany
+    {
+        return $this->belongsToMany(User::class)
+            ->using(RequirementUser::class)
+            ->withPivot(['score']);
+    }
+
+    public function scopeFilter($query, $filters)
+    {
+        return $filters->apply($query);
+    }
+}

+ 18 - 0
app/RequirementUser.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App;
+
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\Pivot;
+
+class RequirementUser extends Pivot
+{
+    use ModelLogChanging;
+
+    public $fillable = ['score'];
+
+    public $incrementing = true;
+
+    public $timestamps = false;
+}

+ 6 - 22
app/Services/BatchService.php

@@ -75,28 +75,16 @@ class BatchService
             $this->instant($this->stationTaskCommodityService,'StationTaskCommodityService');
             $this->instant($this->stationTaskCommodityService,'StationTaskCommodityService');
             $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
             $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
 
 
-            $stationTaskBatches=null;
             $stationTasks=null;
             $stationTasks=null;
-            app('LogService')->log('海柔','assignTasks2',json_encode($batches));
             $batches_shouldProcess = $this->stationRuleBatchService->getBatches_shouldProcess($batches); //按规则过滤需要的波次
             $batches_shouldProcess = $this->stationRuleBatchService->getBatches_shouldProcess($batches); //按规则过滤需要的波次
             if($batches_shouldProcess->isEmpty()) return;
             if($batches_shouldProcess->isEmpty()) return;
-//            $stationTaskMaterialBoxes_occupied = $this->stationTaskMaterialBoxService->getOccupied_byBatches($batches_shouldProcess); //过滤料箱被占用的波次
-//            app('LogService')->log('海柔','assignTasks2.5',json_encode($stationTaskMaterialBoxes_occupied));
-//            if($stationTaskMaterialBoxes_occupied->isNotEmpty()) {
-//                foreach ($batches_shouldProcess as $batch){
-//                    Cache::tags(['波次防重叠'.$batch['id']])->flush();
-//                }
-//                BatchTaskJob::dispatch($batches_shouldProcess)
-//                    ->delay(now()->addMinutes(1));    //因为料箱被占用了,所以将任务推迟1分钟后尝试
-//                return;
-//            }
+
             app('LogService')->log('海柔','assignTasks3',json_encode($batches_shouldProcess));
             app('LogService')->log('海柔','assignTasks3',json_encode($batches_shouldProcess));
-            DB::transaction(function ()use($batches,&$stationTaskBatches,&$batches_shouldProcess,&$stationTasks){
+            DB::transaction(function ()use($batches,&$batches_shouldProcess,&$stationTasks){
                 $stationTasks =  $this->stationTaskService->create($batches_shouldProcess->count()); //生成总任务
                 $stationTasks =  $this->stationTaskService->create($batches_shouldProcess->count()); //生成总任务
-                $stationTaskBatches=$this->stationTaskBatchService->createByBatches($batches_shouldProcess,$stationTasks); //注册波次任务
-                $stationTaskMaterialBoxes=$this->stationTaskMaterialBoxService->createByBatches($batches_shouldProcess,$stationTasks); //注册料箱任务
-                $stationTaskCommodities=$this->stationTaskCommodityService->createByBatches($batches_shouldProcess,$stationTasks); //注册商品任务
-                app('LogService')->log('海柔','assignTasks4',json_encode($batches_shouldProcess));
+                $this->stationTaskBatchService->createByBatches($batches_shouldProcess,$stationTasks); //注册波次任务
+                $this->stationTaskMaterialBoxService->createByBatches($batches_shouldProcess,$stationTasks); //注册料箱任务
+                $this->stationTaskCommodityService->createByBatches($batches_shouldProcess,$stationTasks); //注册商品任务
             });
             });
             foreach ($stationTasks as &$stationTask){
             foreach ($stationTasks as &$stationTask){
                 $stationTask->loadMissing([
                 $stationTask->loadMissing([
@@ -106,19 +94,15 @@ class BatchService
                     "stationTaskMaterialBoxes.materialBox",
                     "stationTaskMaterialBoxes.materialBox",
                 ]);
                 ]);
             }
             }
-            app('LogService')->log('海柔','assignTasks5',json_encode($stationTasks,true).json_encode($batches_shouldProcess));
             $jsonStationTasks=json_encode($stationTasks,true);
             $jsonStationTasks=json_encode($stationTasks,true);
             broadcast(new BroadcastToStation(BroadcastToStation::ALL_STATION, $jsonStationTasks));
             broadcast(new BroadcastToStation(BroadcastToStation::ALL_STATION, $jsonStationTasks));
-            app('LogService')->log('海柔','assignTasks6',$jsonStationTasks.json_encode($batches_shouldProcess));
-//            $ran=$this->stationTaskBatchService->runMany($stationTaskBatches);//执行波次任务
         }catch(Exception $e){
         }catch(Exception $e){
-            app('LogService')->log('海柔','assignTasks7',json_encode($batches));
             $batchesJson='';
             $batchesJson='';
             foreach ($batches as $batch){
             foreach ($batches as $batch){
                 $batchesJson.=json_encode($batch);
                 $batchesJson.=json_encode($batch);
                 Cache::tags(['波次防重叠'.$batch['id']])->flush();
                 Cache::tags(['波次防重叠'.$batch['id']])->flush();
             }
             }
-            app('LogService')->log('海柔','assignTasks8',json_encode($batches));
+            app('LogService')->log('海柔','注册任务失败',$e->getMessage()." | ".json_encode($batches));
             throw new ErrorException('注册任务失败: '. $batchesJson . $e->getMessage().json_encode($e->getTrace()));
             throw new ErrorException('注册任务失败: '. $batchesJson . $e->getMessage().json_encode($e->getTrace()));
         }
         }
     }
     }

+ 26 - 158
app/Services/CacheShelfService.php

@@ -4,16 +4,10 @@ namespace App\Services;
 
 
 use App\Events\BroadcastToStation;
 use App\Events\BroadcastToStation;
 use App\Exceptions\ErrorException;
 use App\Exceptions\ErrorException;
-use App\MaterialBox;
 use App\Station;
 use App\Station;
-use App\StationTask;
-use App\StationTaskChild;
-use App\StationTaskChildren;
 use App\StationTaskMaterialBox;
 use App\StationTaskMaterialBox;
-use App\StationType;
-use App\Storage;
 use App\Traits\ServiceAppAop;
 use App\Traits\ServiceAppAop;
-use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Http;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Database\Eloquent\Collection;
@@ -49,31 +43,36 @@ class   CacheShelfService
     /**
     /**
      * 拍灯触发任务
      * 拍灯触发任务
      * @param $locCode
      * @param $locCode
-     * @param $PTLAction
+     *
      * @return array|bool[]
      * @return array|bool[]
      * @throws \Exception
      * @throws \Exception
      */
      */
-    public function lightOffTask($locCode, $PTLAction): array
+    public function lightOffTask($locCode): array
     {
     {
-        $station = Station::query()->with(['pendingStationTask.stationTaskMaterialBoxes.materialBox','storage'=>function($query){
-            $query->whereNotNull("material_box_id")->orderByDesc("updated_at");
-        }])->where('code', $locCode)->first();
-        //站存在 站为缓存架2 站为蓝灯状态
+        $station = Station::query()->with('materialBox')->where('code', $locCode)->first();
+        if (Cache::has("CACHE_SHELF_OCCUPANCY_{$station->id}")){
+            //缓存存在 不允许灭灯 灭了再点开
+            app("CacheShelfService")->lightUp($station->code,'3','2',["title"=>"库位预定,禁止操作"]);
+            return ['success' => true];
+        }
+        //站存在 站为缓存架
         if (app("StationService")->isHalfBoxLocation($station)){
         if (app("StationService")->isHalfBoxLocation($station)){
-            if (!Storage::query()->where("station_id",$station->id)->whereNotNull("material_box_id")->first())return ['success' => false, 'errMsg' => "任务执行中,不允许灭灯"];
-            if (!app("StorageService")->checkStorage($station)){
+            $result = app("StorageService")->checkStorage($station);
+            if ($result===false){//任务存在且失败 红灯
                 $this->lightUp($station->code,'0','1',["title"=>"上架失败,联系管理员"]);
                 $this->lightUp($station->code,'0','1',["title"=>"上架失败,联系管理员"]);
                 return ['success' => false,'errMsg' => '上架任务失败'];
                 return ['success' => false,'errMsg' => '上架任务失败'];
             };
             };
+            if ($result===true){//任务存在且成功 绿灯
+                $this->lightUp($station->code);
+                return ['success' => true];
+            }
         }
         }
         try {
         try {
             $bool = $this->putBinToStore($station);                         // 推送任务
             $bool = $this->putBinToStore($station);                         // 推送任务
             if ($bool) {
             if ($bool) {
                 LogService::log(__CLASS__, 'lightOffTask', 'code' . ' true' . $locCode . json_encode($station));
                 LogService::log(__CLASS__, 'lightOffTask', 'code' . ' true' . $locCode . json_encode($station));
                 return ['success' => true];
                 return ['success' => true];
-            } else {
-                return ['success' => false, 'errMsg' => '机器人推送失败'];
-            }
+            }else return ['success' => false, 'errMsg' => '机器人推送失败'];
         } catch (ErrorException $e) {
         } catch (ErrorException $e) {
             LogService::log(__FUNCTION__, '缓存架推送任务失败', json_encode($e->getMessage()));
             LogService::log(__FUNCTION__, '缓存架推送任务失败', json_encode($e->getMessage()));
             return ['success' => false, 'errMsg' => $e->getMessage()];
             return ['success' => false, 'errMsg' => $e->getMessage()];
@@ -83,137 +82,21 @@ class   CacheShelfService
     /**
     /**
      * 推任务至海柔机器人
      * 推任务至海柔机器人
      * @param  $station
      * @param  $station
-     * @return array
+     * @return bool
      * @throws ErrorException
      * @throws ErrorException
      * @throws \Exception
      * @throws \Exception
      */
      */
-    public function putBinToStore($station): array
+    public function putBinToStore($station): bool
     {
     {
         $this->instant($this->foreignHaiRoboticsService, 'ForeignHaiRoboticsService');
         $this->instant($this->foreignHaiRoboticsService, 'ForeignHaiRoboticsService');
         $this->instant($this->stationService, 'StationService');
         $this->instant($this->stationService, 'StationService');
 
 
-        /** @var MaterialBox $materialbox */
-        $materialBox = $station->storage->materialbox;
-
-        $formStation = $this->stationService->getStation_byType('立库');          // 立库
-
-        $stationTask = StationTask::query()->create(['station_id' => $formStation['id'], 'status' => '待处理']);   // 生成任务
+        if (!$station->materialBox)return false;
 
 
         /** @var StationTaskMaterialBox $stationTaskMaterialBox */
         /** @var StationTaskMaterialBox $stationTaskMaterialBox */
-        $stationTaskMaterialBox = StationTaskMaterialBox::query()->create([
-            'station_id' => $formStation['id'],
-            'material_box_id' => $materialBox['id'],
-            'status' => '待处理',
-            'station_task_id' => $stationTask['id'],
-            'type' => '放',
-        ]);
-
-        StationTaskChildren::query()->create([
-            'station_task_id' => $stationTask['id'],
-            'station_taskable_type' => StationTaskMaterialBox::class,
-            'station_taskable_id' => $stationTaskMaterialBox['id']
-        ]);
-
-        $bool = $this->foreignHaiRoboticsService->putBinToStore_fromCacheShelf($stationTaskMaterialBox, $station);
-        return $bool ? ['success' => true] : ['success' => false];
-    }
-
-    /**
-     * 缓存架和料箱的绑定
-     * @param $stationCode
-     * @param $materialBoxCode
-     * @return array
-     */
-    public function bindMaterialBox($stationCode, $materialBoxCode): array
-    {
-        $station = Station::query()->with('storage')->where('code', $stationCode)->first();
-
-        if (!$station) {
-            $arr = [];
-            preg_match('/^HAI([\w]+)/', $stationCode, $arr);
-            $parentCode = $arr[1] ?? '';
-            $stationType = StationType::query()->where('name', '缓存架')->first();
-            $parentStation = Station::query()->firstOrCreate(['code' => $parentCode], ['station_type_id' => $stationType['id']]);
-            $station = Station::query()->firstOrCreate(['code' => $stationCode, 'parent_id' => $parentStation['id']], ['name' => $stationCode, 'station_type_id' => $stationType['id']]);
-        }
-
-        $materialBox = MaterialBox::query()->firstOrCreate(['code' => $materialBoxCode]);
-
-        $storage = $station->storage ?? Storage::query()->firstOrCreate(['station_id' => $station['id']]);
-
-        $result = $this->_stationCacheLightOn($station['code'],$materialBoxCode);
-        if($result['code'] == 200){
-            $storage->update(['material_box_id' => $materialBox['id'],'status' => 1]);
-            return ['success' => true];
-        }
-        return ['success' => false,'message' => $result['errMsg']];
-    }
-
-
-    /**
-     * 控制格口亮灯
-     * @param $locCode
-     * @param null $materialCode
-     * @param string $title
-     * @param string $color
-     * @return mixed
-     */
-    public function _stationCacheLightOn($locCode, $materialCode = null, $title = 'title', string $color = '1')
-    {
-        $params = [
-            "areaCode" => "1004",
-            'locCode' => $locCode,
-            'PTLAction' => 1,
-            'PTLSettings' => ['color' => $color, 'frequency' => 1],
-            "displayInfo" => [
-                "detail01" => $materialCode,
-                "detail02" => "detail02",
-                "detail03" => "detail03",
-                "qrCode" => "qrCode",
-                "qty00" => "11",
-                "qty01" => 1,
-                "qty02" => 2,
-                "title" => $title,
-                "uomDesc01" => "uo",
-                "uomDesc02" => "uo"
-            ],
-        ];
-        $response = Http::post(config('api.haiq.storage.light'), $params);
-        return json_decode($response->body());
-    }
+        $stationTaskMaterialBox = app("StorageService")->createWarehousingTask($this->stationService->getStation_byType('立库')["id"],$station->materialBox->id);
 
 
-    /**
-     * 站亮灯
-     *
-     * @param string $stationCode
-     * @param string|null $materialCode
-     * @param string $color             explain: 0-red 1-green 2-blue 3-yellow
-     * @param string $frequency         explain: 0-常亮 1-一次 2-两次 3-三次 4-四次 5-五次 (均为/秒)
-     * @param string $title
-     * @return mixed
-     */
-    public function stationLightUp(string $stationCode,?string $materialCode = null, string $color = '1', string $frequency = '0', $title = '')
-    {
-        $params = [
-            "areaCode" => "1004",
-            'locCode' => $stationCode,
-            'PTLAction' => 1,
-            'PTLSettings' => ['color' => $color, 'frequency'  => $frequency],
-            "displayInfo" => [
-                "detail01" => $materialCode,
-                "detail02" => "detail02",
-                "detail03" => "detail03",
-                "qrCode" => "qrCode",
-                "qty00" => "11",
-                "qty01" => 1,
-                "qty02" => 2,
-                "title" => $title,
-                "uomDesc01" => "uo",
-                "uomDesc02" => "uo"
-            ],
-        ];
-        $response = Http::post(config('api.haiq.storage.light'), $params);
-        return json_decode($response->body());
+        return $this->foreignHaiRoboticsService->putBinToStore_fromCacheShelf($stationTaskMaterialBox, $station);
     }
     }
 
 
     /**
     /**
@@ -233,8 +116,8 @@ class   CacheShelfService
             "detail03" => "",
             "detail03" => "",
             "qrCode" => "",
             "qrCode" => "",
             "qty00" => "",
             "qty00" => "",
-            "qty01" => 0,
-            "qty02" => 0,
+            "qty01" => "",
+            "qty02" => "",
             "title" => '',
             "title" => '',
             "uomDesc01" => "",
             "uomDesc01" => "",
             "uomDesc02" => ""
             "uomDesc02" => ""
@@ -293,21 +176,6 @@ class   CacheShelfService
         }
         }
     }
     }
 
 
-    /**
-     * 根据立库任务完成对storage进行修改
-     * @param StationTaskMaterialBox $stationTaskMaterial
-     */
-    public function putStationTaskMaterialBoxProcess(StationTaskMaterialBox $stationTaskMaterial)
-    {
-        $this->instant($this->stationTaskMaterialBoxService, 'StationTaskMaterialBoxService');
-
-        $storage = Storage::query()->where('material_box_id', $stationTaskMaterial['material_box_id'])->where('status',1)->first();
-        if($storage)$storage->update(['status' => 0, 'material_box_id' => null]);
-
-        $this->_stationCacheLightOff($stationTaskMaterial->station->code ?? null);  //海柔格口灭灯
-        $this->_stationCacheBroadCast($stationTaskMaterial->station->code ?? null, 0);    //通知缓存架任务完成
-    }
-
     /**
     /**
      * 取消任务
      * 取消任务
      * @param $stationCode
      * @param $stationCode
@@ -320,7 +188,7 @@ class   CacheShelfService
 
 
         if (!$station) return ['success' => false, 'message' => '传入参数异常,找不到对应的缓存架记录'];
         if (!$station) return ['success' => false, 'message' => '传入参数异常,找不到对应的缓存架记录'];
 
 
-        $stationTaskMaterialBox = StationTaskMaterialBox::query()->where('material_box_id',$station['storage']['material_box_id'])->first();
+        $stationTaskMaterialBox = StationTaskMaterialBox::query()->where('material_box_id',$station['material_box_id'])->first();
         if($stationTaskMaterialBox ){
         if($stationTaskMaterialBox ){
             if($stationTaskMaterialBox->status == '处理中')
             if($stationTaskMaterialBox->status == '处理中')
                 return ['success' => false, 'message' => '当前缓存架任务正在处理中'];
                 return ['success' => false, 'message' => '当前缓存架任务正在处理中'];
@@ -329,7 +197,7 @@ class   CacheShelfService
             }
             }
         }
         }
 
 
-        $station->storage->update(['status' => 0,'material_box_id' => null]);
+        $station->update(['status' => 0,'material_box_id' => null]);
 
 
         return ['success' => true];
         return ['success' => true];
     }
     }

+ 5 - 6
app/Services/CommodityMaterialBoxModelService.php

@@ -1,4 +1,4 @@
-<?php 
+<?php
 
 
 namespace App\Services;
 namespace App\Services;
 
 
@@ -14,14 +14,13 @@ class CommodityMaterialBoxModelService
     /**
     /**
      * 获取最大限值
      * 获取最大限值
      *
      *
-     * @param integer|null $modelId
-     * @param integer|null $commodityId
+     * @param integer $modelId
+     * @param integer $commodityId
      *
      *
      * @return int|null
      * @return int|null
      */
      */
-    public function getMaximum($modelId, $commodityId):?int
+    public function getMaximum(int $modelId, int $commodityId):?int
     {
     {
-        if (!$modelId || !$commodityId)return null;
         $model = CommodityMaterialBoxModel::query()->select("maximum")->where("commodity_id",$commodityId)
         $model = CommodityMaterialBoxModel::query()->select("maximum")->where("commodity_id",$commodityId)
             ->where("material_box_model_id",$modelId)->first();
             ->where("material_box_model_id",$modelId)->first();
         return (int)$model->maximum ?? null;
         return (int)$model->maximum ?? null;
@@ -48,4 +47,4 @@ class CommodityMaterialBoxModelService
         ]);else $model->update(["maximum" => $maximum]);
         ]);else $model->update(["maximum" => $maximum]);
         return true;
         return true;
     }
     }
-}
+}

+ 79 - 40
app/Services/DbOpenService.php

@@ -2,6 +2,7 @@
 
 
 namespace App\Services;
 namespace App\Services;
 
 
+use App\Log;
 use App\OracleDOCOrderHeader;
 use App\OracleDOCOrderHeader;
 use App\OrderLogistic;
 use App\OrderLogistic;
 use App\Traits\ServiceAppAop;
 use App\Traits\ServiceAppAop;
@@ -20,58 +21,57 @@ class DbOpenService
      * 创建德邦订单,生成快递单号
      * 创建德邦订单,生成快递单号
      * @param array $params
      * @param array $params
      */
      */
-    public function getDbOrderNo($params = [])
+    public function getDbOrderNo(array $params = []):array
     {
     {
         //获取系统无快递单号订单信息
         //获取系统无快递单号订单信息
         $order_info = Waybill::query()
         $order_info = Waybill::query()
-            ->with(['owner:id,name,phone_number', 'orderByCode', 'orderByCode.shop:id,name',
-                'orderByCode.warehouse:id,province_id,city_id,county_id,address',
-                'orderByCode.warehouse.province:id,name', 'orderByCode.warehouse.city:id,name',
-                'orderByCode.warehouse.county:id,name', 'deliveryType:id,name'])
+            ->with(['owner:id,name,phone_number', 'order', 'order.shop:id,name',
+                'order.warehouse:id,province_id,city_id,county_id,address',
+                'order.warehouse.province:id,name', 'order.warehouse.city:id,name',
+                'order.warehouse.county:id,name', 'deliveryType:id,name'])
             ->where('id', '=', $params['id'])
             ->where('id', '=', $params['id'])
             ->first();
             ->first();
         //请求德邦API 生成新订单
         //请求德邦API 生成新订单
         $model = new OrderLogistic();
         $model = new OrderLogistic();
-        $uri = "http://dpsanbox.deppon.com/sandbox-web/dop-standard-ewborder/createOrderNotify.action";
         $header = [
         $header = [
             'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
             'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
             "Accept" => "application/json"
             "Accept" => "application/json"
         ];
         ];
         if ($order_info) {
         if ($order_info) {
-            if (empty($order_info->orderByCode)) return false;
-            $res = $model->isExist($order_info->orderByCode->id);
+            if (empty($order_info->order) || empty($order_info->owner) || empty($order_info->order->shop)) return ['code' => 0, 'msg' => '订单关联信息错误,请核实'];
+            $res = $model->isExist($order_info->order->id);
             if (!$res || $res->status == 0 ?? 0) {
             if (!$res || $res->status == 0 ?? 0) {
                 $data = [
                 $data = [
-                    'logisticID' => config('api_logistic.DB.prod.sign') . date("YmdHis") . mt_rand(1000, 9999) . $order_info->orderByCode->id,
-                    'custOrderNo' => $order_info->orderByCode->client_code ?? '',
+                    'logisticID' => config('api_logistic.DB.prod.sign') . date("YmdHis") . mt_rand(1000, 9999) . $order_info->order->id,
+                    'custOrderNo' => $order_info->order->client_code ?? '',
                     // 'mailNo' => '',  // 不传会创建新的 运单号
                     // 'mailNo' => '',  // 不传会创建新的 运单号
                     'needTraceInfo' => config('api_logistic.DB.prod.needTraceInfo'),
                     'needTraceInfo' => config('api_logistic.DB.prod.needTraceInfo'),
                     'companyCode' => config('api_logistic.DB.prod.company_code'),
                     'companyCode' => config('api_logistic.DB.prod.company_code'),
-                    'orderType' => config('api_logistic.DB.prod.orderType'),
-                    'transportType' => config('api_logistic.DB.prod.transportType'),
+                    'orderType' => $order_info->order_type,
+                    'transportType' => $order_info->transport_type,
                     'customerCode' => config('api_logistic.DB.prod.customer_Code'),
                     'customerCode' => config('api_logistic.DB.prod.customer_Code'),
                     'sender' => [
                     'sender' => [
-                        'companyName' => $order_info->orderByCode->shop->name ?? '',
+                        'companyName' => $order_info->order->shop->name ?? '',
                         'businessNetworkNo' => '',
                         'businessNetworkNo' => '',
                         'name' => $order_info->owner->name ?? '',
                         'name' => $order_info->owner->name ?? '',
                         'mobile' => $order_info->owner->phone_number ?? '',
                         'mobile' => $order_info->owner->phone_number ?? '',
                         'phone' => $order_info->owner->phone_number ?? '',
                         'phone' => $order_info->owner->phone_number ?? '',
-                        'province' => $order_info->orderByCode->warehouse->province->name ?? '',
-                        'city' => $order_info->orderByCode->warehouse->city->name ?? '',
-                        'country' => $order_info->orderByCode->warehouse->county->name ?? '',
+                        'province' => $order_info->order->warehouse->province->name ?? '',
+                        'city' => $order_info->order->warehouse->city->name ?? '',
+                        'country' => $order_info->order->warehouse->county->name ?? '',
                         'town' => '',
                         'town' => '',
-                        'address' => $order_info->orderByCode->warehouse->address ?? '',
+                        'address' => $order_info->order->warehouse->address ?? '',
                     ],
                     ],
                     'receiver' => [
                     'receiver' => [
                         'toNetworkNo' => '',
                         'toNetworkNo' => '',
-                        'name' => $order_info->orderByCode->consignee_name ?? '',
-                        'phone' => $order_info->orderByCode->consignee_phone ?? '',
-                        'mobile' => $order_info->orderByCode->consignee_phone ?? '',
-                        'province' => $order_info->orderByCode->province ?? '',
-                        'city' => $order_info->orderByCode->city ?? "",
-                        'county' => $order_info->orderByCode->district ?? '',
+                        'name' => $order_info->order->consignee_name ?? '',
+                        'phone' => $order_info->order->consignee_phone ?? '',
+                        'mobile' => $order_info->order->consignee_phone ?? '',
+                        'province' => $order_info->order->province ?? '',
+                        'city' => $order_info->order->city ?? "",
+                        'county' => $order_info->order->district ?? '',
                         'town' => '',
                         'town' => '',
-                        'address' => $order_info->orderByCode->address ?? '',
+                        'address' => $order_info->order->address ?? '',
                         'companyName' => ''
                         'companyName' => ''
                     ],
                     ],
                     'packageInfo' => [
                     'packageInfo' => [
@@ -79,25 +79,25 @@ class DbOpenService
                         'totalNumber' => $order_info->total_number ?? '',
                         'totalNumber' => $order_info->total_number ?? '',
                         'totalWeight' => $order_info->total_weight ?? '',
                         'totalWeight' => $order_info->total_weight ?? '',
                         'totalVolume' => '',
                         'totalVolume' => '',
-                        'packageService' => '',
+                        'packageService' => $order_info->package_service ?? '',
                         'deliveryType' => $order_info->deliveryType->name ?? '',
                         'deliveryType' => $order_info->deliveryType->name ?? '',
                     ],
                     ],
                     'gmtCommit' => date('Y-m-d H:i:s'),
                     'gmtCommit' => date('Y-m-d H:i:s'),
-                    'payType' => config('api_logistic.DB.prod.payType'),
+                    'payType' => $order_info->pay_type,
                     'addServices' => [
                     'addServices' => [
                         'insuranceValue' => '',
                         'insuranceValue' => '',
                         'codType' => '',
                         'codType' => '',
                         'reciveLoanAccount' => '',
                         'reciveLoanAccount' => '',
                         'accountName' => '',
                         'accountName' => '',
                         'codValue' => '',
                         'codValue' => '',
-                        'backSignBill' => config('api_logistic.DB.prod.backSignBill')
+                        'backSignBill' => $order_info->back_sign_bill
                     ],
                     ],
                     'smsNotify' => config('api_logistic.DB.prod.smsNotify'),
                     'smsNotify' => config('api_logistic.DB.prod.smsNotify'),
                     'sendStartTime' => date("Y-m-d H:i:s"),
                     'sendStartTime' => date("Y-m-d H:i:s"),
                     'sendEndTime' => $order_info->deliver_at ?? date("Y-m-d H:i:s", strtotime('+1 day')),
                     'sendEndTime' => $order_info->deliver_at ?? date("Y-m-d H:i:s", strtotime('+1 day')),
                     'originalWaybillNumber' => $order_info->wms_bill_number ?? '',
                     'originalWaybillNumber' => $order_info->wms_bill_number ?? '',
                     'remark' => $order_info->dispatch_remark ?? '',
                     'remark' => $order_info->dispatch_remark ?? '',
-                    'isOut' => '',
+                    'isOut' => 'N',
                     'passwordSigning' => config('api_logistic.DB.prod.passwordSigning'),
                     'passwordSigning' => config('api_logistic.DB.prod.passwordSigning'),
                     'isdispatched' => '',
                     'isdispatched' => '',
                     'ispresaleorder' => '',
                     'ispresaleorder' => '',
@@ -107,37 +107,76 @@ class DbOpenService
                         'key' => ''
                         'key' => ''
                     ]
                     ]
                 ];
                 ];
-                $param = json_encode($data, true);
+                $param = json_encode($data,1);
                 $dd["params"] = $param;
                 $dd["params"] = $param;
                 $dd["timestamp"] = (integer)getMillisecond();
                 $dd["timestamp"] = (integer)getMillisecond();
                 $dd["digest"] = base64_encode(md5($param . config('api_logistic.DB.prod.app_key') . $dd['timestamp']));
                 $dd["digest"] = base64_encode(md5($param . config('api_logistic.DB.prod.app_key') . $dd['timestamp']));
                 $dd["companyCode"] = config('api_logistic.DB.prod.company_code');
                 $dd["companyCode"] = config('api_logistic.DB.prod.company_code');
-                $return = httpPost($uri, $dd, $header);
+                $return = httpPost(config('api_logistic.DB.prod.uri')['create_order'], $dd, $header);
                 unset($data);
                 unset($data);
+                $id = $params['id'];
+                $order_no = $order_info->wms_bill_number;
                 if (array_key_exists('result', $return)) {
                 if (array_key_exists('result', $return)) {
                     //请求成功  快递单号 $return['mailNo']   请求编号 $return['uniquerRequestNumber']
                     //请求成功  快递单号 $return['mailNo']   请求编号 $return['uniquerRequestNumber']
+                    //返回日志记录
+                    $mail_no = $return['mailNo']??'';
                     $add_data = [
                     $add_data = [
-                        'order_id' => $order_info->orderByCode->id,
+                        'order_id' => $order_info->order->id,
                         'status' => $return['result'] == 'true' ? 1 : 0,
                         'status' => $return['result'] == 'true' ? 1 : 0,
-                        'code' => $return['mailNo'] ?? '',
+                        'code' => $mail_no ?? '',
                         'uniquer_request_number' => $return['uniquerRequestNumber'],
                         'uniquer_request_number' => $return['uniquerRequestNumber'],
                         'reason' => $return['reason'] ?? '',
                         'reason' => $return['reason'] ?? '',
                         'created_at' => date('Y-m-d H:i:s')
                         'created_at' => date('Y-m-d H:i:s')
                     ];
                     ];
                     $roe = OrderLogistic::query()->insertGetId($add_data);
                     $roe = OrderLogistic::query()->insertGetId($add_data);
-                    //成功
-                    if ($return['result'] == 'true' && $roe) {
-                        $order_no = $order_info->wms_bill_number;
-                        $mail_no = $return['mailNo'];
-                        $row = DB::connection('oracle')->transaction(function () use ($order_no, $mail_no) {
-                            OracleDOCOrderHeader::query()->where('orderno', $order_no)->update(['edittime' => Carbon::now(), 'soreference5' => $mail_no]);
+                    if ($roe && $return['result'] == 'true') {
+                        DB::connection('mysql')->transaction(function () use ($id, $order_no, $mail_no) {
+                            $update_data = [
+                                'type' => '德邦物流',
+                                'waybill_number' => $mail_no,
+                                'updated_at' => date('Y-m-d H:i:s')
+                            ];
+                            Waybill::query()->where('id', '=', $id)->update($update_data);
+                            DB::connection('oracle')->transaction(function () use ($order_no, $mail_no) {
+                                OracleDOCOrderHeader::query()->where('orderno', $order_no)->update(['edittime' => Carbon::now(), 'soreference5' => $mail_no]);
+                            });
                             LogService::log(__METHOD__, "申请快递单号回传WMS", ['orderno' => $order_no, 'soreference5' => $mail_no, 'edittime' => date('Y-m-d H:i:s')]);
                             LogService::log(__METHOD__, "申请快递单号回传WMS", ['orderno' => $order_no, 'soreference5' => $mail_no, 'edittime' => date('Y-m-d H:i:s')]);
                         });
                         });
-                        if ($row) return true;
+                        return ['code' => 1, 'msg' => '申请德邦物流单号成功'];
                     }
                     }
                 }
                 }
+                LogService::log(__METHOD__, "申请快递单号回传WMS", ['orderno' => $order_no, 'content'=> $return]);
+                return ['code' => 0, 'msg' => $return['reason']];
             }
             }
+            elseif($res->status == 1 ?? 0 ) return ['code' => 1, 'msg'=> '德邦快递单号已存在'];
         }
         }
-        return false;
+        return ['code' => 0, 'msg' => '订单信息错误,请核实'];
+    }
+
+    /**
+     * 根据 德邦运单号 获取 订单物流轨迹
+     * @param array $params
+     * @return array
+     */
+    public function getOrderStatus(array $params = []):array
+    {
+        if ( ($params['mailNo']??'') == '') return ['code' => 0 , 'msg' => '德邦运单号不能为空'];
+        $header = [
+            'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
+            "Accept" => "application/json"
+        ];
+        $data = [
+            'mailNo' => $params['mailNo']??''
+        ];
+        $param = json_encode($data, 1);
+        $dd["params"] = $param;
+        $dd["timestamp"] = (integer)getMillisecond();
+        $dd["digest"] = base64_encode(md5($param . config('api_logistic.DB.prod.app_key') . $dd['timestamp']));
+        $dd["companyCode"] = config('api_logistic.DB.prod.company_code');
+        $return = httpPost(config('api_logistic.DB.prod.uri')['order_locus'], $dd, $header);
+        if (array_key_exists('result', $return) && $return['result'] == 'true' && array_key_exists('resultCode', $return) && $return['resultCode'] == '1000'){
+           return ['code'=> 1, 'msg'=> '正在加载中。。。', 'data' => $return['responseParam']];
+        }
+        return ['code' => 0, 'msg' => '暂无物流信息'];
     }
     }
 }
 }

+ 6 - 38
app/Services/ForeignHaiRoboticsService.php

@@ -22,7 +22,6 @@ use App\Traits\ServiceAppAop;
 class ForeignHaiRoboticsService
 class ForeignHaiRoboticsService
 {
 {
     use ServiceAppAop;
     use ServiceAppAop;
-//    protected $modelClass=ForeignHaiRobotics::class;
 
 
     /** @var  $stationTaskMaterialBoxService StationTaskMaterialBoxService */
     /** @var  $stationTaskMaterialBoxService StationTaskMaterialBoxService */
     private $stationTaskMaterialBoxService;
     private $stationTaskMaterialBoxService;
@@ -142,24 +141,21 @@ class ForeignHaiRoboticsService
      * @param string $groupIdPrefix
      * @param string $groupIdPrefix
      * @param string $mode
      * @param string $mode
      * @return bool
      * @return bool
-     * @throws ErrorException
+     * @throws ErrorException|Exception
      */
      */
-    public function fetchGroup_multiLocation(Collection $toLocations, Collection $taskMaterialBoxes, $groupIdPrefix='',$mode='立架出至输送线'): bool
+    public function fetchGroup_multiLocation(Collection $toLocations, Collection $taskMaterialBoxes, $groupIdPrefix='', $mode='立架出至输送线', int $priority = 10): bool
     {
     {
         $dataToPost=$this->makeJson_move_multi(
         $dataToPost=$this->makeJson_move_multi(
             $taskMaterialBoxes,
             $taskMaterialBoxes,
             $mode,
             $mode,
             null,
             null,
             $toLocations,
             $toLocations,
-            $groupIdPrefix
+            $groupIdPrefix,
+            $priority
         );
         );
         return $this->controlHaiRobot($dataToPost,$taskMaterialBoxes,$mode);
         return $this->controlHaiRobot($dataToPost,$taskMaterialBoxes,$mode);
     }
     }
 
 
-    public function moveBin(){
-
-    }
-
     public function markBinProcessed(
     public function markBinProcessed(
         $workStation,
         $workStation,
         $binCode,
         $binCode,
@@ -184,17 +180,9 @@ class ForeignHaiRoboticsService
                 throw new ErrorException('海柔任务失败:'.$exception);
                 throw new ErrorException('海柔任务失败:'.$exception);
             LogService::log('海柔请求','markBinProcessed1.3',
             LogService::log('海柔请求','markBinProcessed1.3',
                 $failed);
                 $failed);
-//            if($NotInPlan
-//                =!$is_in_plan)
-//                throw new ErrorException('海柔认为是计划外的料箱:'.$exception);
-
-            LogService::log('海柔请求','markBinProcessed1.4',
-                '$NotInPlan');
 
 
             $materialBox=
             $materialBox=
                 $this->materialBoxService->get(['code'=>$binCode])->first();
                 $this->materialBoxService->get(['code'=>$binCode])->first();
-            LogService::log('海柔请求','markBinProcessed1.5',
-                json_encode($materialBox));
             /** @var StationTaskMaterialBox $stationTaskMaterialBox */
             /** @var StationTaskMaterialBox $stationTaskMaterialBox */
             $stationTaskMaterialBox
             $stationTaskMaterialBox
                 =(function()use($materialBox){
                 =(function()use($materialBox){
@@ -206,13 +194,9 @@ class ForeignHaiRoboticsService
                         ->orderBy('id','desc')
                         ->orderBy('id','desc')
                     ->first();
                     ->first();
             })();
             })();
-            LogService::log('海柔请求','markBinProcessed1.6',
-                json_encode($stationTaskMaterialBox).'|'.$binCode);
             if(!$stationTaskMaterialBox){
             if(!$stationTaskMaterialBox){
                 throw new ErrorException($binCode.'该料箱没有安排在处理队列中.');
                 throw new ErrorException($binCode.'该料箱没有安排在处理队列中.');
             }
             }
-            LogService::log('海柔请求','markBinProcessed1.7',
-                json_encode($stationTaskMaterialBox).'|'.$binCode);
 
 
             DB::transaction(function ()use($stationTaskMaterialBox,$binCode){
             DB::transaction(function ()use($stationTaskMaterialBox,$binCode){
                 $stationTaskMaterialBox_next=
                 $stationTaskMaterialBox_next=
@@ -235,8 +219,6 @@ class ForeignHaiRoboticsService
                         json_encode($stationTaskMaterialBox['stationTaskBatch']).'|'.$binCode);
                         json_encode($stationTaskMaterialBox['stationTaskBatch']).'|'.$binCode);
                     $stationTaskMaterialBox->loadMissing('stationTaskBatch');
                     $stationTaskMaterialBox->loadMissing('stationTaskBatch');
                     $this->stationTaskBatchService->markProcessed($stationTaskMaterialBox['stationTaskBatch']);
                     $this->stationTaskBatchService->markProcessed($stationTaskMaterialBox['stationTaskBatch']);
-                    LogService::log('海柔请求','markBinProcessed1.82',
-                        json_encode($stationTaskMaterialBox['stationTaskBatch']).'|'.$binCode);
                     $this->stationTaskService->markProcessed($stationTaskMaterialBox['stationTask']);
                     $this->stationTaskService->markProcessed($stationTaskMaterialBox['stationTask']);
                 }
                 }
                 $this->storeBox($stationTaskMaterialBox)
                 $this->storeBox($stationTaskMaterialBox)
@@ -409,20 +391,6 @@ class ForeignHaiRoboticsService
         return true;
         return true;
     }
     }
 
 
-//    public function markHasPut($taskCode,$binCode):bool{
-//        try{
-//            //标记料箱进入位置
-////            $taskMaterialBoxesService->markDone();//
-//        }catch (\Exception $e){
-//            switch ($e->getCode()){
-//                case 'taskBinNotMatch';
-//                case 'taskGetFailed';
-//            }
-//        }
-//
-//    }
-
-
     public function excepted($taskCode='',$binCode='', $msg=''):bool{
     public function excepted($taskCode='',$binCode='', $msg=''):bool{
         try{
         try{
             throw new ErrorException(
             throw new ErrorException(
@@ -510,13 +478,13 @@ class ForeignHaiRoboticsService
      *
      *
      * @throws
      * @throws
      */
      */
-    public function paddingCacheShelf($stations)
+    public function paddingCacheShelf(Collection $stations):?bool
     {
     {
         $collection = new Collection();
         $collection = new Collection();
         $stationCollection = new Collection();
         $stationCollection = new Collection();
         $blacklist = [];
         $blacklist = [];
         foreach ($stations as $station){
         foreach ($stations as $station){
-            $box = app("MaterialBoxService")->getAnEmptyBox($blacklist);
+            $box = app("MaterialBoxService")->getAnEmptyBoxSortedByOwner(null,$blacklist);
             if (!$box)break;
             if (!$box)break;
             $task = StationTask::query()->create([
             $task = StationTask::query()->create([
                 'status' => "待处理",
                 'status' => "待处理",

+ 393 - 0
app/Services/HandInStorageService.php

@@ -0,0 +1,393 @@
+<?php
+
+namespace App\Services;
+
+use App\OracleBasCode;
+use App\OracleBasSKU;
+use App\OracleDOCASNDetail;
+use App\OracleDOCASNHeader;
+use App\OracleInvLotAtt;
+use App\Traits\ServiceAppAop;
+use App\ValueStore;
+use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
+
+class HandInStorageService
+{
+    use ServiceAppAop;
+
+    /**
+     * @param $asn
+     * @return Builder[]|Collection
+     * 获取富勒asn_header
+     *
+     */
+    public function selectAsn($asn)
+    {
+        if ($asn) return OracleDOCASNHeader::query()
+            ->with('asnStatus')
+            ->select(['asnno','asnreference1','asnstatus','addtime','customerid'])
+            ->where('asnno',$asn)
+            ->get();
+
+        return OracleDOCASNHeader::query()
+            ->select(['asnno','asnreference1','asnstatus','addtime','customerid'])
+            ->with('asnStatus')
+            ->where('asnstatus','00')
+            ->orderByDesc('addtime')
+            ->limit(50)
+            ->get();
+    }
+
+    /**
+     * @param $asnno
+     * @return Builder[]|Collection
+     * 获取富勒asn_detail (集合)
+     */
+    public function selectAsnDetails($asnno)
+    {
+        return OracleDOCASNDetail::query()
+            ->select(['sku','expectedqty','skudescrc','asnlineno','asnno','receivedqty'])
+            ->where('asnno',$asnno)
+            ->get();
+    }
+
+    /**
+     * @param $asnno
+     * @param $sku
+     * @return Builder|Model|object|null
+     *
+     */
+    public function getAsnDetail($asnno,$sku)
+    {
+        return OracleDOCASNDetail::query()
+            ->select(['sku','expectedqty','skudescrc','asnlineno','asnno','receivedqty'])
+            ->where('asnno',$asnno)
+            ->where('sku',$sku)
+            ->first();
+    }
+
+    /**
+     * @return mixed
+     * 获取质量状态
+     */
+    public function getQualityStatus()
+    {
+        return Cache::remember('BAS_CODE_QLT_STS', 600, function () {
+            return OracleBasCode::query()->select(['codeid','code','codename_c'])
+                ->where('codeid','QLT_STS')
+                ->get();
+        });
+    }
+
+    /**
+     * @return mixed
+     * 获取属性仓
+     */
+    public function getAttributeLocation()
+    {
+        return Cache::remember('BAS_CODE_CUS_UDFPC', 600, function () {
+            return OracleBasCode::query()->select(['codeid','code','codename_c'])
+                ->where('codeid','CUS_UDFPC')
+                ->get();
+        });
+    }
+
+    /**
+     * @param $customerid
+     * @param $sku
+     * @return mixed
+     * 根据customerid和sku 查询商品关联的批次属性规则
+     */
+    public function getBasSkuLotId($customerid,$sku)
+    {
+        return Cache::remember('bas_sku_lot_'.$customerid.'_'.$sku, 600, function ()use($customerid,$sku) {
+            return OracleBasSKU::query()->select(['customerid','sku','lotid'])
+                ->where('customerid',$customerid)
+                ->where('sku',$sku)
+                ->with('lotId')
+                ->first();
+        });
+    }
+
+    /**
+     * @throws \Throwable
+     */
+    public function fluxHandIn(array $info)
+    {
+        $lotatt=array_filter($info,function ($key){
+            return strpos($key,'lotatt')===0;
+        },ARRAY_FILTER_USE_KEY);
+        $invlotatt=[];
+        for ($i=1;$i<=8;$i++){$invlotatt["lotatt0{$i}"]=null;}
+        foreach ($invlotatt as $key=>&$item){
+            foreach ($lotatt as $key1=>$item1){
+                if ($key===$key1) $item=$item1;
+            }
+        }
+        $who= 'WAS'.(Auth::user() ? '-'.Auth::user()["name"] : '');
+        $time=Carbon::now()->toDateTimeString();
+//        return DB::connection("oracle")->transaction(function ()use ($info,$invlotatt,$who,$time){
+            //flux 批次号
+//            $lotNum=$this->getOrCreateLotNum($info,$invlotatt,$who,$time);
+//            if (!$lotNum) return false;
+            //flux 创建入库事务
+//            $actTransactionLog=$this->setFluxActTransactionLog($info,$lotNum,$who,$time);
+//            if (!$actTransactionLog)return false;
+            //flux 创建上架任务
+//            $this->setFluxTskTaskListPA($info,$invlotatt, $actTransactionLog, $who, $time);
+            //flux 完善库存余量
+//            $this->updateFluxInv($info,$lotNum,$who,$time,$actTransactionLog);
+            //flux 更新asn_detail 和 asn_header 状态
+            $re=$this->updateFluxAsn($info,$invlotatt,$time,$who);
+            dd($re);
+//            return true;
+//        });
+
+    }
+
+    /**
+     * @throws \Throwable
+     */
+    public function updateFluxAsn(array $info, array $invlotatt, $time, $who): bool
+    {
+        $db=DB::connection("oracle");
+        $asn=OracleDOCASNHeader::query()
+            ->withCount('asnDetails')
+            ->with('asnDetails')
+            ->where('asnno',$info['asnno'])
+            ->first();
+        if (!$asn||!$asn->asnDetails||!$asn->asn_details_count) return false;
+        $asnDetails=$asn->asnDetails;
+        $receiveAsn=null;
+        foreach ($asnDetails as $asnDetail){
+            if ($asnDetail['asnno']==$info['asnno'] &&
+                $asnDetail['asnlineno']==$info['asnlineno'] &&
+                $asnDetail['customerid']==$info['customerid'] &&
+                $asnDetail['sku']==$info['sku']) $receiveAsn=$asnDetail;
+        }
+        return $db->transaction(function ()use($db,$info,$receiveAsn,$invlotatt,$time,$who){
+            if ($receiveAsn && (int)$receiveAsn['receivedqty']+(int)$info['amount']<(int)$receiveAsn['expectedqty']){
+                //asn_detail 收货数量+已收数量<预期数量
+                $db->update(DB::raw("UPDATE DOC_ASN_DETAILS SET linestatus = '30',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ?,
+             lotatt01=?,lotatt02=?,lotatt03=?,lotatt04=?,lotatt05=?,lotatt06=?,lotatt07=?,lotatt08=? WHERE asnno = ?"),
+                    [$time,$who,$invlotatt['lotatt01'],$invlotatt['lotatt02'],$invlotatt['lotatt03'],$invlotatt['lotatt04'],
+                        $invlotatt['lotatt05'],$invlotatt['lotatt06'],$invlotatt['lotatt07'],$invlotatt['lotatt08'],$info['asnno']]);
+                //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 linestatus = '40',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ?,
+             lotatt01=?,lotatt02=?,lotatt03=?,lotatt04=?,lotatt05=?,lotatt06=?,lotatt07=?,lotatt08=? WHERE asnno = ?"),
+                    [$time,$who,$invlotatt['lotatt01'],$invlotatt['lotatt02'],$invlotatt['lotatt03'],$invlotatt['lotatt04'],
+                        $invlotatt['lotatt05'],$invlotatt['lotatt06'],$invlotatt['lotatt07'],$invlotatt['lotatt08'],$info['asnno']]);
+                //当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']]);
+                }
+            }
+            return true;
+        });
+    }
+    /**
+     * @throws \Throwable
+     */
+    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 = ?"),[
+                (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'),?)"),[
+                $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']
+            ]);
+
+            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"),[
+                    $lotNum,$info['location'],$actTransactionLog['customerid'],$actTransactionLog['sku'],$actTransactionLog['trackid']
+                ]);
+
+                if ($invLotIdHasPreLocation)$db->update(DB::raw("UPDATE inv_lot_loc_id SET qtypa = qtypa+?,edittime=?,editwho=? WHERE lotnum = ? AND locationid = ? AND traceid = ?"),[
+                    (int)$info['amount'],$time,$who,$lotNum,$info['location'],$actTransactionLog['trackid']
+                ]);
+                else $db->insert(DB::raw("INSERT INTO inv_lot_loc_id VALUES(?,?,?,?,?,?,0,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,'*',?,null)"),[
+                    $lotNum,$info['location'],$actTransactionLog['trackid'],$actTransactionLog['customerid'],$actTransactionLog['sku'],0,$time,$who,$time,$who,(int)$info['amount']
+                ]);
+
+                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,
+                ]);
+
+            }else{
+                if ($invLotId)$db->update(DB::raw("UPDATE inv_lot_loc_id SET qty = qty+?,edittime=?,editwho=? WHERE lotnum = ? AND locationid = ? AND traceid = ?"),[
+                    (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,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'],$time,$who,$time,$who,
+                ]);
+            }
+        });
+    }
+
+    /**
+     * @throws \Throwable
+     */
+    public function setFluxTskTaskListPA(array $info, array $invlotatt, $actTransactionLog, $who, $time)
+    {
+        $db = DB::connection("oracle");
+        $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']
+            ]);
+        });
+    }
+
+    /**
+     * @param array $info
+     * @param $lotNum
+     * @param $who
+     * @param $time
+     * @return mixed
+     * @throws \Throwable
+     * 创建入库事务
+     */
+    public function setFluxActTransactionLog(array $info,$lotNum,$who,$time)
+    {
+        $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
+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;
+        });
+    }
+    /**
+     * @param array $info
+     * @return mixed
+     * @throws \Throwable
+     * 或去flux 批次号
+     */
+    public function getOrCreateLotNum(array $info,array $invlotatt,$who,$time)
+    {
+        $invlotatt['customerid']=$info['customerid'];
+        $invlotatt['sku']=$info['sku'];
+        //根据批次规则查询或新建批次
+        $lotnum=OracleInvLotAtt::query()->where($invlotatt)->value('lotnum');
+        if ($lotnum) return $lotnum;
+
+        $db = DB::connection("oracle");
+        list($num,$max)=$this->getLtNum();
+        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;
+       });
+
+    }
+
+    /**
+     * 获取批次号
+     * @return array
+     */
+    private function getLtNum()
+    {
+        $val = ValueStore::query()->select("value")->where("name","flux_lt_number")->lockForUpdate()->first();
+        if (!$val)$val = ValueStore::query()->create(["name"=>"flux_lt_number","value"=>'0']);
+        $max = $val->value+1;
+        $number = sprintf("%07d", $max);
+        return array ('WLT'.$number,$max);
+    }
+
+    /**
+     * 设置批次号
+     */
+    private function setLtNum()
+    {
+        ValueStore::query()
+            ->select("value")
+            ->where("name","flux_lt_number")
+            ->update(["value"=>DB::raw("value+1")]);
+    }
+    /**
+     * 获取批次号
+     * @return array
+     */
+    private function getTsNum()
+    {
+        $val = ValueStore::query()->select("value")->where("name","flux_ts_number")->lockForUpdate()->first();
+        if (!$val)$val = ValueStore::query()->create(["name"=>"flux_ts_number","value"=>'0']);
+        $max = $val->value+1;
+        $number = sprintf("%07d", $max);
+        return array ('WTS'.$number,$max);
+    }
+
+    /**
+     * 设置批次号
+     */
+    private function setTsNum()
+    {
+        ValueStore::query()
+            ->select("value")
+            ->where("name","flux_ts_number")
+            ->update(["value"=>DB::raw("value+1")]);
+    }
+}

+ 5 - 1
app/Services/LogisticSFService.php

@@ -54,7 +54,11 @@ class LogisticSFService
      */
      */
     public function getResultFromSF(string $head, string $numbers, string $checkWord, string $url): array
     public function getResultFromSF(string $head, string $numbers, string $checkWord, string $url): array
     {
     {
-        $responseBody = get_object_vars(simplexml_load_string($this->sendHttpToSF($head, $numbers, $checkWord, $url))->Body)['RouteResponse'];
+        try {
+            $responseBody = get_object_vars(simplexml_load_string($this->sendHttpToSF($head, $numbers, $checkWord, $url))->Body)['RouteResponse'];
+        } catch (Exception $e) {//index RouteResponse 异常处理
+            return [];
+        }
         $result = [];
         $result = [];
         if (is_array($responseBody)) {//SF返回多个单号的查询结果
         if (is_array($responseBody)) {//SF返回多个单号的查询结果
             $result = $this->transformSFMoreToArr($responseBody, $result);
             $result = $this->transformSFMoreToArr($responseBody, $result);

+ 39 - 0
app/Services/MaterialBoxModelService.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Services;
+
+use App\Owner;
+use App\Traits\ServiceAppAop;
+use App\MaterialBoxModel;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\DB;
+
+class MaterialBoxModelService
+{
+    use ServiceAppAop;
+    protected $modelClass=MaterialBoxModel::class;
+
+    /**
+     * 获取货主的模型序列
+     *
+     * @param int|null $owner
+     *
+     * @return Collection
+     */
+    public function getModelSortedByOwner(?int $owner):Collection
+    {
+        $sequence = [];
+        $sql = "(CASE id ";
+        if (!$owner){
+            $owner = Owner::query()->find($owner);
+            if ($owner){
+                $sequence = explode(",",$owner->model_sequence);
+                foreach ($sequence as $index=>$s)$sql .= " WHEN {$s} THEN {$index}";
+                $sql .= " END)";
+            }
+        }
+        $query = MaterialBoxModel::query();
+        if ($sequence)$query->whereIn("id",$sequence)->orderBy(DB::raw($sql));
+        return $query->get();
+    }
+}

+ 20 - 25
app/Services/MaterialBoxService.php

@@ -5,12 +5,8 @@ namespace App\Services;
 
 
 
 
 use App\MaterialBox;
 use App\MaterialBox;
-use App\Station;
+use App\MaterialBoxModel;
 use App\StationTaskMaterialBox;
 use App\StationTaskMaterialBox;
-use App\Storage;
-use Illuminate\Database\Eloquent\Builder;
-use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Cache;
 use App\Traits\ServiceAppAop;
 use App\Traits\ServiceAppAop;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\DB;
 
 
@@ -24,12 +20,12 @@ class MaterialBoxService
     /**
     /**
      * 获取一个空料箱
      * 获取一个空料箱
      *
      *
+     * @param MaterialBoxModel|\stdClass $model
      * @param array $blacklist
      * @param array $blacklist
-     * @param integer|null $modelId
      *
      *
      * @return MaterialBox|null
      * @return MaterialBox|null
      */
      */
-    public function getAnEmptyBox(array $blacklist = [], $modelId = null)
+    public function getAnEmptyBox(MaterialBoxModel $model,array $blacklist = []):?MaterialBox
     {
     {
         $id = 0;
         $id = 0;
         while (true){
         while (true){
@@ -39,8 +35,8 @@ class MaterialBoxService
                 ->where("id",">",$id)->where("code","like","IDE%")
                 ->where("id",">",$id)->where("code","like","IDE%")
                 ->where("status",4)->limit(50)->orderBy("id")
                 ->where("status",4)->limit(50)->orderBy("id")
                 ->whereNotIn("id",StationTaskMaterialBox::query()->select("material_box_id")
                 ->whereNotIn("id",StationTaskMaterialBox::query()->select("material_box_id")
-                    ->where("status","!=","完成")->groupBy("material_box_id"));
-            if ($modelId)$boxes->where("material_box_model_id",$modelId);
+                    ->whereNotIn("status",["完成","取消"])
+                    ->where("material_box_model_id",$model->id)->groupBy("material_box_id"));
             $boxes = $boxes->get();
             $boxes = $boxes->get();
             if ($boxes->count()==0)break;
             if ($boxes->count()==0)break;
             $id = $boxes[count($boxes)-1]->id;
             $id = $boxes[count($boxes)-1]->id;
@@ -56,7 +52,7 @@ class MaterialBoxService
                 ->whereNotIn("status",[0,4])->get();
                 ->whereNotIn("status",[0,4])->get();
             $haiBoxes->each(function ($haiBox)use(&$notCodes){$notCodes[$haiBox->bin_code] = true;});
             $haiBoxes->each(function ($haiBox)use(&$notCodes){$notCodes[$haiBox->bin_code] = true;});
 
 
-            //检测FLUX
+            //剔除FLUX已有库存并且库位内种类超出的料箱
             $ides = [];
             $ides = [];
             $str = "(";
             $str = "(";
             foreach ($boxes as $box){
             foreach ($boxes as $box){
@@ -67,30 +63,31 @@ class MaterialBoxService
             if (!$ides)continue;
             if (!$ides)continue;
             $str = rtrim($str,",").")";
             $str = rtrim($str,",").")";
             $sql = <<<sql
             $sql = <<<sql
-SELECT LOCATIONID,SUM(QTY+QTYPA) qty FROM INV_LOT_LOC_ID WHERE LOCATIONID IN {$str} GROUP BY LOCATIONID
+SELECT LOCATIONID FROM (SELECT LOCATIONID FROM (SELECT LOCATIONID,SUM(QTY+QTYPA) qty FROM INV_LOT_LOC_ID WHERE LOCATIONID IN {$str} GROUP BY LOCATIONID,LOTNUM,CUSTOMERID,SKU) where qty>0) GROUP BY
+                            LOCATIONID HAVING (COUNT(*)>={$model->maximum_kind})
 sql;
 sql;
-            foreach (DB::connection("oracle")->select(DB::raw($sql)) as $item){
-                if ((int)$item->qty==0)return $ides[$item->locationid];
-                unset($ides[$item->locationid]);
-            }
+            foreach (DB::connection("oracle")->select(DB::raw($sql)) as $item)unset($ides[$item->locationid]);
             if ($ides)return current($ides);
             if ($ides)return current($ides);
         }
         }
         return null;
         return null;
     }
     }
 
 
     /**
     /**
-     * 获取料箱所在库区
+     * 获取所有者排序的空盒子
      *
      *
-     * @param string $ide
+     * @param integer|null $ownerId
+     * @param array $blacklist
      *
      *
-     * @return string|null
+     * @return MaterialBox|null
      */
      */
-    public function getBoxLocation(string $ide):?string
+    public function getAnEmptyBoxSortedByOwner(?int $ownerId=null, array $blacklist=[]):?MaterialBox
     {
     {
-        $storage = Storage::query()->with("station")->whereHas("materialBox",function (Builder $box)use($ide){
-            $box->where("code",$ide);
-        })->whereNotNull("station_id")->first();
-        return $storage->station->code ?? null;
+        $models = app("MaterialBoxModelService")->getModelSortedByOwner($ownerId);
+        foreach ($models as $model){
+            $box = $this->getAnEmptyBox($model,$blacklist);
+            if ($box)return $box;
+        }
+        return null;
     }
     }
 
 
     /**
     /**
@@ -103,8 +100,6 @@ sql;
     public function checkUsableBox(int $boxId):bool
     public function checkUsableBox(int $boxId):bool
     {
     {
         /** @var MaterialBox|\stdClass $box */
         /** @var MaterialBox|\stdClass $box */
-        //$box = MaterialBox::query()->find($boxId);
-        //if (!$this->getBoxLocation($box->code))return false;
         if (StationTaskMaterialBox::query()->select(DB::raw(1))->whereNotIn("status",['完成','取消'])->where("material_box_id",$boxId)->first())return false;
         if (StationTaskMaterialBox::query()->select(DB::raw(1))->whereNotIn("status",['完成','取消'])->where("material_box_id",$boxId)->first())return false;
         return true;
         return true;
     }
     }

+ 2 - 5
app/Services/NewOrderCountingRecordService.php

@@ -487,9 +487,6 @@ class NewOrderCountingRecordService
         return $ttl;
         return $ttl;
     }
     }
 
 
-
-    //TODO 控制台重构
-
     public function getWareHouseRecordsApi($start, $end, $ownerIds): array
     public function getWareHouseRecordsApi($start, $end, $ownerIds): array
     {
     {
         $orderCountingRecords = OrderCountingRecord::query()
         $orderCountingRecords = OrderCountingRecord::query()
@@ -670,11 +667,11 @@ class NewOrderCountingRecordService
             $end = now()->subMonth()->endOfDay();
             $end = now()->subMonth()->endOfDay();
         }
         }
         $endDate = Carbon::parse($end)->endOfDay()->toDateString();
         $endDate = Carbon::parse($end)->endOfDay()->toDateString();
-        $records = OrderCountingRecord::query()
+        OrderCountingRecord::query()
             ->selectRaw("owner_id,warehouse_id,logistic_id,sum(amount) as amount_sum,month,year,date_target")
             ->selectRaw("owner_id,warehouse_id,logistic_id,sum(amount) as amount_sum,month,year,date_target")
             ->whereBetween('date_target', [$startDate, $endDate])
             ->whereBetween('date_target', [$startDate, $endDate])
             ->where('counting_unit', '日')
             ->where('counting_unit', '日')
-            ->groupBy('owner_id', 'warehouse_id', 'logistic_id', 'month', 'date_target')
+            ->groupBy('owner_id', 'warehouse_id', 'logistic_id', 'month')
             ->chunk(1000, function ($records) use ($unit) {
             ->chunk(1000, function ($records) use ($unit) {
                 $insertData = [];
                 $insertData = [];
                 foreach ($records as $record) {
                 foreach ($records as $record) {

+ 1 - 0
app/Services/OrderCommodityService.php

@@ -31,6 +31,7 @@ class OrderCommodityService
         }
         }
     }
     }
 
 
+    //暂时无意义,直到下个版本前仍未被引用则删除
     public function correctLocation_fromWMS($orderCommodities){
     public function correctLocation_fromWMS($orderCommodities){
         $orderCommodities->loadMissing('order.batch');
         $orderCommodities->loadMissing('order.batch');
         $details=OracleActAllocationDetails::query()
         $details=OracleActAllocationDetails::query()

+ 2 - 1
app/Services/OrderPackageReceivedSyncService.php

@@ -104,7 +104,8 @@ class OrderPackageReceivedSyncService
                 if ($orderPackage && $orderPackage->logistic_number)LogisticAliJiSuSync::dispatch($orderPackage->logistic_number);
                 if ($orderPackage && $orderPackage->logistic_number)LogisticAliJiSuSync::dispatch($orderPackage->logistic_number);
             }
             }
         });
         });
-        $this->syncLogisticRouteJD();
+        //TODO 暂时不同步京东
+//        $this->syncLogisticRouteJD();
     }
     }
     public function syncLogisticRouteJD(){
     public function syncLogisticRouteJD(){
         ini_set('max_execution_time', 60);
         ini_set('max_execution_time', 60);

+ 21 - 7
app/Services/OwnerBillReportArchiveService.php

@@ -2,8 +2,6 @@
 
 
 namespace App\Services;
 namespace App\Services;
 
 
-use App\OwnerAreaReport;
-use App\OwnerBillReport;
 use App\Traits\ServiceAppAop;
 use App\Traits\ServiceAppAop;
 use App\OwnerBillReportArchive;
 use App\OwnerBillReportArchive;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Builder;
@@ -23,7 +21,7 @@ class OwnerBillReportArchiveService
      */
      */
     public function getSql($counting_month, $owner_id, $type): Builder
     public function getSql($counting_month, $owner_id, $type): Builder
     {
     {
-        return OwnerBillReportArchive::query()->where('counting_month', $counting_month)
+        return OwnerBillReportArchive::query()->where('counting_month', \Carbon\Carbon::parse($counting_month)->toDateString())
             ->where('owner_id', $owner_id)->where('type', $type);
             ->where('owner_id', $owner_id)->where('type', $type);
     }
     }
 
 
@@ -31,12 +29,11 @@ class OwnerBillReportArchiveService
      * @param $counting_month
      * @param $counting_month
      * @param $owner_id
      * @param $owner_id
      * @param $type
      * @param $type
-     * @return int
+     * @return int 1 已确认 2 未确认
      */
      */
     public function isArchived($counting_month, $owner_id, $type): int
     public function isArchived($counting_month, $owner_id, $type): int
     {
     {
-        $type = $this->switchType($type);
-        return $this->getSql($counting_month, $owner_id, $type)->exists() ? 1 : 2;
+        return $this->getSql($counting_month, $owner_id, $this->switchType($type))->exists() ? 1 : 2;
     }
     }
 
 
     /**
     /**
@@ -55,10 +52,27 @@ class OwnerBillReportArchiveService
      */
      */
     private function switchType($type)
     private function switchType($type)
     {
     {
-//枚举转换
+        //枚举转换
         if (is_string($type)) {
         if (is_string($type)) {
             $type = OwnerBillReportArchive::$enums['type'][$type];
             $type = OwnerBillReportArchive::$enums['type'][$type];
         }
         }
         return $type;
         return $type;
     }
     }
+
+    /**
+     *查询没有确认的账单
+     */
+    public function getUnAchieved($counting_month, $owner_id): array
+    {
+        //TODO   5 => "包材费"
+        //  8 => "卸货费"
+        //  9 => "理赔费"
+        //]
+        $archives = OwnerBillReportArchive::query()
+            ->where('counting_month', $counting_month)
+            ->where('owner_id', $owner_id)
+            ->pluck('type')->toArray();
+        $all = ['仓储费', '快递费-合计', '入库费-合计', '出库费-合计', '物流费', '包材费', '加工费', '杂项费', '卸货费', '理赔费',];
+        return array_diff($all, $archives);
+    }
 }
 }

+ 74 - 0
app/Services/OwnerDischargeTaskSettlementBillService.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace App\Services;
+
+use App\DischargeTask;
+use App\Traits\ServiceAppAop;
+use App\Traits\SettlementBillServiceTrait;
+
+class OwnerDischargeTaskSettlementBillService implements \App\Interfaces\SettlementBillReportInterface
+{
+    use \App\Traits\SettlementBillServiceTrait;
+    const TYPE = '卸货费';
+
+    use ServiceAppAop;
+
+    public function get(array $kvPairs): array
+    {
+        $details = $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->paginate($kvPairs['paginateParams']['paginate'] ?? 50);
+        $totalFee = $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->sum('expenditure_total_cost');
+        return array($details, $totalFee);
+    }
+
+
+    public function getSql($owner_id, $counting_month): \Illuminate\Database\Eloquent\Builder
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+
+        return DischargeTask::query()
+            ->where('owner_id', $owner_id)
+            ->whereBetween('income_at', [$start, $end]);
+    }
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        $result = [];
+        foreach ($details as $detail) {
+            $result[] = [
+                $detail->income_at,
+                $detail->type,
+                $detail->numbers,
+                $detail->expenditure_amount,
+                $detail->expenditure_unit,
+                $detail->expenditure_unit_price,
+                $detail->expenditure_total_cost,
+                $detail->income_remark,
+                $detail->expenditure_remark,
+            ];
+        }
+        return $result;
+    }
+
+    public function add(array $model)
+    {
+        // TODO: Implement add() method.
+    }
+
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        return $this->getSql($owner_id, $counting_month)->sum('expenditure_total_cost');
+    }
+
+
+    public function recordReport($counting_month = null)
+    {
+        // TODO: Implement recordReport() method.
+    }
+}
+
+

+ 465 - 0
app/Services/OwnerFeeTotalService.php

@@ -0,0 +1,465 @@
+<?php
+
+namespace App\Services;
+
+use App\OrderIssue;
+use App\Owner;
+use App\OwnerBillReport;
+use App\OwnerPriceOperation;
+use App\OwnerPriceOperationItem;
+use App\Traits\ServiceAppAop;
+use App\OwnerFeeTotal;
+use App\Traits\SettlementBillServiceTrait;
+use Illuminate\Database\Eloquent\Builder;
+
+class OwnerFeeTotalService
+{
+    const TYPE = '总费用';
+    use ServiceAppAop;
+
+    use SettlementBillServiceTrait;
+
+    protected $modelClass = OwnerFeeTotal::class;
+
+    /**
+     * 生成统计数据
+     * @param string|null $counting_month string 统计月份默认为上一个月
+     */
+    public function record(string $counting_month = null)
+    {
+        if (is_null($counting_month)) {
+            $counting_month = now()->subMonth()->startOfMonth()->toDateString();
+        }
+        /**
+         * 仓储。入库,出库
+         * 1. 查到所有货主
+         * 2. 遍历货主
+         * 3. 获得货主下的计费模型,将计费模型里面的数据转换成“描述”
+         * 4. 查询相关表,获得指定计费模型下的费用总和(含税费)
+         *
+         * 配送,加工,系统使用,杂项
+         * 1. 查询对应表的总和即可,不需关联计费模型
+         *
+         * 理赔
+         * 1. 暂不明确
+         *
+         * 优惠
+         * 1. 一个字段,在结算管理-账单却认下添加一个优惠输入的字段
+         *
+         * 税率
+         * 1. 计算得出:总税费/总金额
+         */
+        //仓储:ownerStoragePriceModels。入库,出库:ownerPriceOperations
+        $owners = Owner::query()
+            ->with([
+                "ownerStoragePriceModels.unit:id,name",
+                "ownerStoragePriceModels.timeUnit:id,name",
+                "ownerPriceOperations" => function ($query) {
+                    /** @var Builder $query */
+                    $query->with(["items" => function ($query) {
+                        /** @var Builder $query */
+                        $query->with(['unit'])->orderByRaw("CASE strategy  WHEN '起步' THEN 1 WHEN '默认' THEN 2 WHEN '特征' THEN 3 END");
+                    }]);
+                }])
+            ->where('deleted_at', '>=', now()->subMonth()->startOfMonth())
+            ->orWhereNull('deleted_at')->get();
+        foreach ($owners as $owner) {
+            $information = $this->buildInformation($owner, $counting_month);
+            $ownerFeeTotal = [];
+            $ownerFeeTotal['information'] = $information;
+            //快递费
+            $ownerFeeTotal = $this->buildExpressFee($owner, $counting_month, $ownerFeeTotal);
+            //物流费
+            $ownerFeeTotal = $this->buildLogisticFee($owner, $counting_month, $ownerFeeTotal);
+            //加工
+            $ownerFeeTotal = $this->buildProcessFee($owner, $counting_month, $ownerFeeTotal);
+            //系统使用费
+            $ownerFeeTotal = $this->buildSystemFee($counting_month, $owner, $ownerFeeTotal);
+            //杂项费
+            $ownerFeeTotal = $this->buildSundryFee($owner, $counting_month, $ownerFeeTotal);
+            //理赔
+            $ownerFeeTotal = $this->buildIndemnityFee($counting_month, $owner, $ownerFeeTotal);
+            // 包材费
+            $ownerFeeTotal = $this->buildPackingMaterialFee($owner, $counting_month, $ownerFeeTotal);
+            // 卸货费
+            $ownerFeeTotal = $this->buildUnloadFee($owner, $counting_month, $ownerFeeTotal);
+            //总费用 和 总税费
+            list($totalFee, $totalTaxFee, $ownerFeeTotal) = $this->calTotalFeeAndTotalTaxFee($ownerFeeTotal);
+            //税率
+            $ownerFeeTotal = $this->calTaxRate($totalTaxFee, $totalFee, $ownerFeeTotal);
+            $insertData = $this->buildInsertData($owner, $counting_month, $ownerFeeTotal);
+            $this->createOrUpdate($owner, $counting_month, $insertData);
+        }
+    }
+
+    public function get(array $kvPairs)
+    {
+        return OwnerFeeTotal::query()
+            ->where('owner_id', $kvPairs['owner_id'])
+            ->where('counting_month', $kvPairs['counting_month'])
+            ->first();
+    }
+
+    /**
+     * 出库入库描述
+     * @param $ownerPriceOperation
+     * @return array
+     */
+    private function buildPriceRemarks($ownerPriceOperation): array
+    {
+        //起步: 3 件 / 2.7000元  (满减单价: 0-19999 单(2.7元) , 20000-49999 单(2.5元) , 50000-99999 单(2元) , 100000+ 单(1.6元) )
+        //默认续费: 1 件 / 0.5000元  (满减单价: 0-19999 单(0.5元) , 20000-49999 单(0.4元) , 50000-99999 单(0.3元) , 100000+ 单(0.2元) )
+        $discount_counts = explode(',', $ownerPriceOperation->discount_count);
+        $priceRemarks = [];
+        foreach ($ownerPriceOperation->items as $operationItem) {
+            $discount_prices = explode(',', $operationItem->discount_price);
+            $strategy = $operationItem->strategy == '起步' ? '起步' : '默认续费';
+            $unit_name = $operationItem->unit->name ?? '个';
+            $priceRemark = "{$strategy}: {$operationItem->amount} {$unit_name}/{$operationItem->unit_price}元";
+            if (!empty($discount_prices)) {
+                $priceRemark .= "(满减单价:";
+                for ($i = 0; $i < count($discount_counts) - 1; $i++) {
+                    $next_discount_count = $discount_counts[$i + 1] ?? '+';
+                    $discount_count = $discount_counts[$i] ?? '';
+                    $discount_price = $discount_prices[$i] ?? '';
+                    $priceRemark .= "{$discount_count}-{$next_discount_count} {$unit_name} {$discount_price}元,";
+                }
+                $priceRemark .= ")";
+            }
+            $priceRemarks[] = $priceRemark;
+        }
+        return $priceRemarks;
+    }
+
+
+    /**
+     * @param $owner
+     * @param $counting_month
+     * @return array|array[]
+     */
+    private function buildInformation($owner, $counting_month): array
+    {
+        //获取特征信息
+        $features = app("FeatureService")->getMapArray();
+        OwnerPriceOperation::$features = $features;
+        OwnerPriceOperationItem::$features = $features;
+        foreach ($owner->ownerPriceOperations as &$operation) {
+            $operation["featureFormat"] = $operation->featureFormat;
+            $operation["isRejected"] = $operation->type_mark === 0;
+            foreach ($operation->items as &$item) {
+                $item["featureFormat"] = $item->featureFormat;
+                if ($item["strategy"] == "起步") $item["type"] = $item["amount"] ? 0 : 1;
+            }
+        }
+
+        $information = [
+            //仓储
+            'storageFee' => [],
+            //入库
+            'storeFee' => [],
+            //出库
+            'storeOutFee' => [],
+        ];
+        //仓储
+        foreach ($owner->ownerStoragePriceModels as $ownerStoragePriceModel) {
+            /**@var $areaFeeService SettlementBillsAreaFeeService */
+            $areaFeeService = app('SettlementBillsAreaFeeService');
+            $remark = "起租面积:{$ownerStoragePriceModel->minimum_area},{$ownerStoragePriceModel->price[0]}元/{$ownerStoragePriceModel->unit->name}/{$ownerStoragePriceModel->timeUnit->name}";
+            $information['storageFee'][] = [
+                'name' => $ownerStoragePriceModel->name,
+                'remark' => $remark,
+                'id' => $ownerStoragePriceModel->id,
+                'fee' => number_format($areaFeeService->getTotalFee($owner->id, $counting_month)->storage_fee ?? 0, 2),
+                'tax_fee' => $areaFeeService->getTotalFee($owner->id, $counting_month)->storage_tax_fee ?? 0
+            ];
+        }
+
+        $ownerPriceOperationsGrouped = $owner->ownerPriceOperations->groupBy('operation_type');
+        /**@var $storeOutFeeDetailsService OwnerStoreOutFeeDetailService */
+        $storeOutFeeDetailsService = app('OwnerStoreOutFeeDetailService');
+        $workFeeTotalGrouped = $storeOutFeeDetailsService->getTotalFee($owner->id, $counting_month)->groupBy('owner_price_operation_id');
+
+        //入库
+        foreach ($ownerPriceOperationsGrouped['入库'] ?? [] as $ownerPriceOperationsGroupedItem) {
+            $information['storeFee'][] = [
+                'name' => $ownerPriceOperationsGroupedItem->name,
+                'remark' => $this->buildPriceRemarks($ownerPriceOperationsGroupedItem),
+                'id' => $ownerPriceOperationsGroupedItem->id,
+                'fee' => number_format($workFeeTotalGrouped[$ownerPriceOperationsGroupedItem->id][0]->work_fee ?? 0, 2),
+                'tax_fee' => $workFeeTotalGrouped[$ownerPriceOperationsGroupedItem->id][0]->work_tax_fee ?? 0,
+            ];
+        }
+
+        //出库
+        foreach ($ownerPriceOperationsGrouped['出库'] ?? [] as $ownerPriceOperationsGroupedItem) {
+            $information['storeOutFee'][] = [
+                'name' => $ownerPriceOperationsGroupedItem->name,
+                'remark' => $this->buildPriceRemarks($ownerPriceOperationsGroupedItem),
+                'id' => $ownerPriceOperationsGroupedItem->id,
+                'fee' => number_format($workFeeTotalGrouped[$ownerPriceOperationsGroupedItem->id][0]->work_fee ?? 0, 2),
+                'tax_fee' => number_format($workFeeTotalGrouped[$ownerPriceOperationsGroupedItem->id][0]->work_tax_fee ?? 0, 2),
+            ];
+        }
+        return $information;
+    }
+
+    /**
+     * @param $owner
+     * @param string|null $counting_month
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function buildExpressFee($owner, ?string $counting_month, array $ownerFeeTotal): array
+    {
+        /**@var $expressFeeService OwnerLogisticFeeReportService */
+        $expressFeeService = app('OwnerLogisticFeeReportService');
+        $expressFeeTotal = $expressFeeService->getTotalFee($owner->id, $counting_month);
+        $ownerFeeTotal ['expressFee'] = [
+            'fee' => $expressFeeTotal->fee ?? 0,
+            'tax_fee' => $expressFeeTotal->tax_fee ?? 0,
+        ];
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param $owner
+     * @param string|null $counting_month
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function buildLogisticFee($owner, ?string $counting_month, array $ownerFeeTotal): array
+    {
+        /**@var $waybillSettlementBillService OwnerWaybillSettlementBillService */
+        $waybillSettlementBillService = app('OwnerWaybillSettlementBillService');
+        $logisticFeeTotal = $waybillSettlementBillService->getTotalFee($owner->id, $counting_month);
+        $ownerFeeTotal ['logisticFee'] = [
+            'fee' => $logisticFeeTotal->fee ?? 0,
+            'tax_fee' => $logisticFeeTotal->tax_fee ?? 0,
+        ];
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param $owner
+     * @param string|null $counting_month
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function buildProcessFee($owner, ?string $counting_month, array $ownerFeeTotal): array
+    {
+        /**@var $ownerProcessSettlementBillService OwnerProcessSettlementBillService */
+        $ownerProcessSettlementBillService = app('OwnerProcessSettlementBillService');
+        $processFeeTotal = $ownerProcessSettlementBillService->getTotalFee($owner->id, $counting_month);
+        $ownerFeeTotal ['processFee'] = [
+            'fee' => $processFeeTotal->fee ?? 0,
+            'tax_fee' => $processFeeTotal->tax_fee ?? 0,
+        ];
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param string|null $counting_month
+     * @param $owner
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function buildSystemFee(?string $counting_month, $owner, array $ownerFeeTotal): array
+    {
+        $ownerBillReport = OwnerBillReport::query()
+            ->where('counting_month', $counting_month)
+            ->where('owner_id', $owner->id)
+            ->first();
+        $ownerFeeTotal ['systemFee'] = [
+            'fee' => $ownerBillReport->other_fee ?? 0,
+            'tax_fee' => $ownerBillReport->other_tax_fee ?? 0,
+        ];
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param $owner
+     * @param string|null $counting_month
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function buildSundryFee($owner, ?string $counting_month, array $ownerFeeTotal): array
+    {
+        /**@var $ownerSundryFeeDetailService OwnerSundryFeeDetailService */
+        $ownerSundryFeeDetailService = app('OwnerSundryFeeDetailService');
+        $sundryFeeTotals = $ownerSundryFeeDetailService->getTotalFee($owner->id, $counting_month);
+        if (!$sundryFeeTotals->isEmpty()) {
+            foreach ($sundryFeeTotals as $sundryFeeTotal) {
+                $ownerFeeTotal ['sundryFee'][] = [
+                    'type' => $sundryFeeTotal->type,
+                    'fee' => $sundryFeeTotal->fee,
+                ];
+            }
+        } else {
+            $ownerFeeTotal ['sundryFee'] = [];
+        }
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param string|null $counting_month
+     * @param $owner
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function buildIndemnityFee(?string $counting_month, $owner, array $ownerFeeTotal): array
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        $indemnityFee = OrderIssue::query()
+            ->selectRaw("sum(baoshi_indemnity_money) as fee,owner_id,order_id")
+            ->leftJoin('orders', 'order_issues.order_id', '=', 'orders.id')
+            ->where('owner_id', $owner->id)
+            ->whereBetween('order_issues.created_at', [$start, $end])->first();
+        $ownerFeeTotal ['indemnityFee'] = [
+            'fee' => $indemnityFee->fee ?? 0,
+        ];
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param $owner
+     * @param string|null $counting_month
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function buildPackingMaterialFee($owner, ?string $counting_month, array $ownerFeeTotal): array
+    {
+        /**@var $packingMaterialFeeService OwnerProcurementSettlementBillService */
+        $packingMaterialFeeService = app('OwnerProcurementSettlementBillService');
+        $packingMaterialFee = $packingMaterialFeeService->getTotalFee($owner->id, $counting_month);
+        $ownerFeeTotal ['packingMaterialFee'] = [
+            'fee' => $packingMaterialFee ?? 0,
+        ];
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param $owner
+     * @param string|null $counting_month
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function buildUnloadFee($owner, ?string $counting_month, array $ownerFeeTotal): array
+    {
+        /**@var $unloadService OwnerDischargeTaskSettlementBillService */
+        $unloadService = app('OwnerDischargeTaskSettlementBillService');
+        $unloadFee = $unloadService->getTotalFee($owner->id, $counting_month);
+        $ownerFeeTotal ['unloadFee'] = [
+            'fee' => $unloadFee ?? 0,
+        ];
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param array $ownerFeeTotal
+     * @return array
+     */
+    private function calTotalFeeAndTotalTaxFee(array $ownerFeeTotal): array
+    {
+        $totalFee = 0;
+        $totalTaxFee = 0;
+        foreach ($ownerFeeTotal as $key => $ownerFeeTotalItem) {
+            if ($key == 'information') {
+                list($totalFee, $totalTaxFee) = $this->calInformationTotalFeeAndTotalTaxFee($ownerFeeTotalItem, $totalFee, $totalTaxFee);
+            } else if ($key == 'sundryFee') {
+                foreach ($ownerFeeTotalItem as $sundryFeeItem) {
+                    $totalFee += $sundryFeeItem['fee'] ?? 0;
+                }
+            } else {
+                $totalFee += $ownerFeeTotalItem['fee'] ?? 0;
+                $totalTaxFee += $ownerFeeTotalItem['tax_fee'] ?? 0;
+            }
+
+        }
+        $ownerFeeTotal['totalFee'] = $totalFee;
+        $ownerFeeTotal['totalTaxFee'] = $totalTaxFee;
+        return array($totalFee, $totalTaxFee, $ownerFeeTotal);
+    }
+
+    /**
+     * @param $totalTaxFee
+     * @param $totalFee
+     * @param $ownerFeeTotal
+     * @return mixed
+     */
+    private function calTaxRate($totalTaxFee, $totalFee, $ownerFeeTotal)
+    {
+        try {
+            $taxRate = number_format(($totalTaxFee / $totalFee) * 100, 2) ?? 0;
+        } catch (\Exception $e) {
+            $taxRate = 0;
+        }
+        $ownerFeeTotal['taxRate'] = $taxRate;
+        return $ownerFeeTotal;
+    }
+
+    /**
+     * @param $owner
+     * @param string|null $counting_month
+     * @param $ownerFeeTotal
+     * @return array
+     */
+    private function buildInsertData($owner, ?string $counting_month, $ownerFeeTotal): array
+    {
+        return [
+            'owner_id' => $owner->id,
+            'counting_month' => $counting_month,
+            'information' => $ownerFeeTotal['information'],
+            'fee' => $ownerFeeTotal['totalFee'],
+            'logistic_fee' => $ownerFeeTotal['logisticFee']['fee'],
+            'logistic_tax_fee' => $ownerFeeTotal['logisticFee']['tax_fee'],
+            'express_fee' => $ownerFeeTotal['expressFee']['fee'],
+            'express_tax_fee' => $ownerFeeTotal['expressFee']['tax_fee'],
+            'process_fee' => $ownerFeeTotal['processFee']['fee'],
+            'process_tax_fee' => $ownerFeeTotal['processFee']['tax_fee'],
+            'system_fee' => $ownerFeeTotal['systemFee']['fee'],
+            'system_tax_fee' => $ownerFeeTotal['systemFee']['tax_fee'],
+            'sundry_information' => $ownerFeeTotal['sundryFee'],
+            'packing_material_fee' => $ownerFeeTotal['packingMaterialFee']['fee'],
+            'unload_fee' => $ownerFeeTotal['unloadFee']['fee'],
+            'tax_rate' => $ownerFeeTotal['taxRate'],
+            'indemnity_fee' => $ownerFeeTotal['indemnityFee']['fee'],
+        ];
+    }
+
+    /**
+     * @param $ownerFeeTotalItem
+     * @param $totalFee
+     * @param $totalTaxFee
+     * @return array|int[]
+     */
+    private function calInformationTotalFeeAndTotalTaxFee($ownerFeeTotalItem, $totalFee, $totalTaxFee): array
+    {
+        foreach ($ownerFeeTotalItem as $ownerFeeTotalItemOne) {
+            foreach ($ownerFeeTotalItemOne as $feeItem) {
+                $totalFee += $feeItem['fee'] ?? 0;
+                $totalTaxFee += $feeItem['tax_fee'] ?? 0;
+            }
+        }
+        return array($totalFee, $totalTaxFee);
+    }
+
+    /**
+     * @param $owner
+     * @param string|null $counting_month
+     * @param array $insertData
+     */
+    private function createOrUpdate($owner, ?string $counting_month, array $insertData): void
+    {
+        if (OwnerFeeTotal::query()->where('owner_id', $owner->id)->where('counting_month', $counting_month)->exists()) {
+            OwnerFeeTotal::query()
+                ->where('owner_id', $owner->id)
+                ->where('counting_month', $counting_month)
+                ->update($insertData);
+        } else {
+            OwnerFeeTotal::query()
+                ->where('owner_id', $owner->id)
+                ->where('counting_month', $counting_month)
+                ->create($insertData);
+        }
+    }
+}

+ 27 - 15
app/Services/OwnerLogisticFeeDetailService.php

@@ -6,13 +6,14 @@ use App\Logistic;
 use App\OwnerFeeDetail;
 use App\OwnerFeeDetail;
 use App\Traits\ServiceAppAop;
 use App\Traits\ServiceAppAop;
 use App\OwnerLogisticFeeDetail;
 use App\OwnerLogisticFeeDetail;
+use App\Traits\SettlementBillServiceTrait;
 use Carbon\Carbon;
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Pagination\LengthAwarePaginator;
 use Illuminate\Pagination\LengthAwarePaginator;
-use Illuminate\Support\Collection;
 
 
-class OwnerLogisticFeeDetailService
+class OwnerLogisticFeeDetailService implements \App\Interfaces\SettlementBillDetailInterface
 {
 {
+    use SettlementBillServiceTrait;
     const TYPE = '快递费-明细';
     const TYPE = '快递费-明细';
 
 
     use ServiceAppAop;
     use ServiceAppAop;
@@ -22,20 +23,15 @@ class OwnerLogisticFeeDetailService
      */
      */
     protected $modelClass = OwnerLogisticFeeDetail::class;
     protected $modelClass = OwnerLogisticFeeDetail::class;
 
 
-    //插入数据 ServiceAppAop的 insert 方法 支持批量
 
 
     /**
     /**
      * 根据货主查询 和时间段查询
      * 根据货主查询 和时间段查询
-     * @param string $owner_id
-     * @param string $start
-     * @param string $end
-     * @param $paginateParams
+     * @param array $kvPairs
      * @return LengthAwarePaginator
      * @return LengthAwarePaginator
      */
      */
-    public function getDetails(string $owner_id, string $start, string $end, $paginateParams): LengthAwarePaginator
+    public function get(array $kvPairs): LengthAwarePaginator
     {
     {
-        $ownerLogisticFeeDetails = $this->getSql($owner_id, $start, $end)
-            ->paginate($paginateParams['paginate'] ?? 50);
+        $ownerLogisticFeeDetails = $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->paginate($kvPairs['paginateParams']['paginate'] ?? 50);
         $items = $this->buildDetails($ownerLogisticFeeDetails);
         $items = $this->buildDetails($ownerLogisticFeeDetails);
         return new LengthAwarePaginator(
         return new LengthAwarePaginator(
             $items,
             $items,
@@ -65,13 +61,11 @@ class OwnerLogisticFeeDetailService
     }
     }
 
 
     /**
     /**
-     * @param string $owner_id
-     * @param string $start
-     * @param string $end
      * @return Builder
      * @return Builder
      */
      */
-    public function getSql(string $owner_id, string $start, string $end): Builder
+    public function getSql($owner_id, $counting_month): Builder
     {
     {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
         return OwnerLogisticFeeDetail::query()->with([
         return OwnerLogisticFeeDetail::query()->with([
             'ownerFeeDetail:id,province,weight,logistic_fee',
             'ownerFeeDetail:id,province,weight,logistic_fee',
             'ownerFeeDetailLogistic:id,weight,logistic_fee,logistic_bill',
             'ownerFeeDetailLogistic:id,weight,logistic_fee,logistic_bill',
@@ -97,9 +91,27 @@ class OwnerLogisticFeeDetailService
                 'weight' => $ownerLogisticFeeDetail->ownerFeeDetailLogistic->weight ?? $ownerLogisticFeeDetail->ownerFeeDetail->weight ?? '0.00',//重量
                 'weight' => $ownerLogisticFeeDetail->ownerFeeDetailLogistic->weight ?? $ownerLogisticFeeDetail->ownerFeeDetail->weight ?? '0.00',//重量
                 'initial_weight_price' => $ownerLogisticFeeDetail->initial_weight_price ?? '',//首重价格
                 'initial_weight_price' => $ownerLogisticFeeDetail->initial_weight_price ?? '',//首重价格
                 'additional_price' => $ownerLogisticFeeDetail->additional_price ?? '',//续重价格
                 'additional_price' => $ownerLogisticFeeDetail->additional_price ?? '',//续重价格
-                'logistic_fee' => $ownerLogisticFeeDetail->ownerFeeDetailLogistic->logistic_fee ?? $ownerLogisticFeeDetail->ownerFeeDetail->logistic_fee ?? '0.00',//快递费
+//                'logistic_fee' => $ownerLogisticFeeDetail->ownerFeeDetailLogistic->logistic_fee ?? $ownerLogisticFeeDetail->ownerFeeDetail->logistic_fee ?? '0.00',//快递费
+                'logistic_fee' => $ownerLogisticFeeDetail->fee,//快递费
             ];
             ];
         }
         }
         return $items;
         return $items;
     }
     }
+
+    public function switchType($type)
+    {
+    }
+
+    public function buildExport($details): array
+    {
+    }
+
+    public function add(array $model)
+    {
+    }
+
+    public function getTotalFee($owner_id, $counting_month)
+    {
+    }
+
 }
 }

+ 82 - 8
app/Services/OwnerLogisticFeeReportService.php

@@ -2,6 +2,8 @@
 
 
 namespace App\Services;
 namespace App\Services;
 
 
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
 use App\OwnerLogisticFeeDetail;
 use App\OwnerLogisticFeeDetail;
 use App\Traits\ServiceAppAop;
 use App\Traits\ServiceAppAop;
 use App\OwnerLogisticFeeReport;
 use App\OwnerLogisticFeeReport;
@@ -10,10 +12,12 @@ use Illuminate\Contracts\Pagination\LengthAwarePaginator;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Database\Eloquent\Collection;
 
 
-class OwnerLogisticFeeReportService
+class OwnerLogisticFeeReportService implements \App\Interfaces\SettlementBillReportInterface
 {
 {
     const TYPE = '快递费-合计';
     const TYPE = '快递费-合计';
+
     use ServiceAppAop;
     use ServiceAppAop;
+    use \App\Traits\SettlementBillServiceTrait;
 
 
     protected $modelClass = OwnerLogisticFeeReport::class;
     protected $modelClass = OwnerLogisticFeeReport::class;
 
 
@@ -21,6 +25,44 @@ class OwnerLogisticFeeReportService
     /** @var  $archiveService OwnerBillReportArchiveService */
     /** @var  $archiveService OwnerBillReportArchiveService */
     private $archiveService;
     private $archiveService;
 
 
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        // TODO: Implement buildExport() method.
+    }
+
+    public function confirmBill($counting_month, $owner_id)
+    {
+        $billReport = OwnerBillReport::query()
+            ->select('storage_fee', 'id')
+            ->where('owner_id', $owner_id)
+            ->where('counting_month', $counting_month)
+            ->firstOr(function () {
+                return new OwnerBillReport();
+            });
+        $reports = $this->getRecords($owner_id, $counting_month);
+        $recordTotal = $this->getRecordTotal($owner_id, $counting_month);
+        OwnerBillReportArchive::query()->create([
+            'owner_bill_report_id' => $billReport->id ?? null,
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this::TYPE,
+            'archiver_id' => auth()->id(),
+            'archived_at' => now(),
+            'information' => [
+                'reports' => $reports,
+                'recordTotal' => $recordTotal,
+            ],
+        ]);
+        $this->confirmBillFeeTotal($counting_month, $owner_id);
+    }
+
+
     /**
     /**
      * 生成报表数据
      * 生成报表数据
      * 如果参数$counting_month为空 统计上一个月的
      * 如果参数$counting_month为空 统计上一个月的
@@ -40,7 +82,20 @@ class OwnerLogisticFeeReportService
 
 
 
 
         $ownerLogisticFeeDetails = OwnerLogisticFeeDetail::query()
         $ownerLogisticFeeDetails = OwnerLogisticFeeDetail::query()
-            ->selectRaw("logistic_id,province,DATE_FORMAT(created_at,'%Y-%m-%d') as counted_date,initial_weight,initial_weight_price,count(1) as initial_amount,additional_price,additional_weight,sum(additional_weigh_weight) as additional_amount,created_at,owner_id")
+            ->selectRaw("logistic_id,
+            province,
+            DATE_FORMAT(created_at,
+            '%Y-%m') as counted_date,
+            initial_weight,
+            initial_weight_price,
+            count(1) as initial_amount,
+            additional_price,
+            additional_weight,
+            sum(additional_weigh_weight) as additional_amount,
+            sum(tax_fee) as tax_fee,
+            sum(fee) as fee,
+            created_at,
+            owner_id")
             ->whereBetween('created_at', [$start, $end])
             ->whereBetween('created_at', [$start, $end])
             ->groupBy('initial_weight', 'initial_weight_price', 'additional_price', 'additional_weight', 'logistic_id', 'province', 'counted_date', 'owner_id')
             ->groupBy('initial_weight', 'initial_weight_price', 'additional_price', 'additional_weight', 'logistic_id', 'province', 'counted_date', 'owner_id')
             ->get();
             ->get();
@@ -57,10 +112,14 @@ class OwnerLogisticFeeReportService
                 'additional_weight' => $ownerLogisticFeeDetail->additional_weight,
                 'additional_weight' => $ownerLogisticFeeDetail->additional_weight,
                 'additional_price' => $ownerLogisticFeeDetail->additional_price,
                 'additional_price' => $ownerLogisticFeeDetail->additional_price,
                 'additional_amount' => $ownerLogisticFeeDetail->additional_amount,
                 'additional_amount' => $ownerLogisticFeeDetail->additional_amount,
-                'fee' => ($ownerLogisticFeeDetail['initial_weight_price'] * $ownerLogisticFeeDetail['initial_amount']) + ($ownerLogisticFeeDetail['additional_amount'] * $ownerLogisticFeeDetail['additional_price']),
+                'fee' => $ownerLogisticFeeDetail->fee,
+                'tax_fee' => $ownerLogisticFeeDetail->tax_fee,
                 'owner_id' => $ownerLogisticFeeDetail->owner_id,
                 'owner_id' => $ownerLogisticFeeDetail->owner_id,
             ];
             ];
         }
         }
+        //保证接口幂等性 删除统计月的数据
+        OwnerLogisticFeeReport::query()->where('counted_date', $counting_month)->delete();
+
         OwnerLogisticFeeReport::query()->insertOrIgnore($ownerLogisticFeeReportArray);
         OwnerLogisticFeeReport::query()->insertOrIgnore($ownerLogisticFeeReportArray);
     }
     }
 
 
@@ -71,7 +130,7 @@ class OwnerLogisticFeeReportService
      * @param $paginateParams
      * @param $paginateParams
      * @return LengthAwarePaginator
      * @return LengthAwarePaginator
      */
      */
-    private function getRecordPagination($owner_id, string $counting_month, $paginateParams): LengthAwarePaginator
+    private function getPagination($owner_id, string $counting_month, $paginateParams): LengthAwarePaginator
     {
     {
         return $this->getSql($owner_id, $counting_month)
         return $this->getSql($owner_id, $counting_month)
             ->paginate($paginateParams['paginate'] ?? 50);
             ->paginate($paginateParams['paginate'] ?? 50);
@@ -81,12 +140,14 @@ class OwnerLogisticFeeReportService
     {
     {
         $this->archiveService = app('OwnerBillReportArchiveService');
         $this->archiveService = app('OwnerBillReportArchiveService');
         if ($this->archiveService->isArchived($kvPairs['counting_month'], $kvPairs['owner_id'], $kvPairs['type']) == 1) {
         if ($this->archiveService->isArchived($kvPairs['counting_month'], $kvPairs['owner_id'], $kvPairs['type']) == 1) {
+            //查询存档数据
             $archived = $this->archiveService->get($kvPairs);
             $archived = $this->archiveService->get($kvPairs);
-            $reports =collect($archived->information['reports']);
+
+            $reports = collect($archived->information['reports']);
             $recordTotal = $archived->information['recordTotal'];
             $recordTotal = $archived->information['recordTotal'];
         } else {
         } else {
             $recordTotal = $this->getRecordTotal($kvPairs['owner_id'], $kvPairs['counting_month']);
             $recordTotal = $this->getRecordTotal($kvPairs['owner_id'], $kvPairs['counting_month']);
-            $reports = $this->getRecordPagination($kvPairs['owner_id'], $kvPairs['counting_month'], $kvPairs['paginateParams']);
+            $reports = $this->getPagination($kvPairs['owner_id'], $kvPairs['counting_month'], $kvPairs['paginateParams']);
         }
         }
         return array($reports, $recordTotal);
         return array($reports, $recordTotal);
     }
     }
@@ -126,10 +187,10 @@ class OwnerLogisticFeeReportService
 
 
     /**
     /**
      * @param $owner_id
      * @param $owner_id
-     * @param string $counting_month
+     * @param  $counting_month
      * @return Builder
      * @return Builder
      */
      */
-    public function getSql($owner_id, string $counting_month): Builder
+    public function getSql($owner_id, $counting_month): Builder
     {
     {
         return OwnerLogisticFeeReport::query()
         return OwnerLogisticFeeReport::query()
             ->with('logistic:id,name')
             ->with('logistic:id,name')
@@ -138,4 +199,17 @@ class OwnerLogisticFeeReportService
             ->orderByDesc('logistic_id')
             ->orderByDesc('logistic_id')
             ->orderByDesc('province');
             ->orderByDesc('province');
     }
     }
+
+    /**
+     *获取总金额和税费
+     */
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        return OwnerLogisticFeeReport::query()
+            ->selectRaw("sum(fee) as fee,
+            sum(tax_fee) as tax_fee")
+            ->where('owner_id', $owner_id)
+            ->where('counted_date', $counting_month)
+            ->first();
+    }
 }
 }

+ 2 - 2
app/Services/OwnerPriceOperationService.php

@@ -398,7 +398,6 @@ class OwnerPriceOperationService
      */
      */
     private function resetChildNodeMapping($matchObject,&$columnMapping)
     private function resetChildNodeMapping($matchObject,&$columnMapping)
     {
     {
-        dump($matchObject,$columnMapping);
         $need = "";
         $need = "";
         foreach (Feature::TYPE_NODE as $index){
         foreach (Feature::TYPE_NODE as $index){
             if (!$need)$need=strstr($columnMapping[$index],".",true);
             if (!$need)$need=strstr($columnMapping[$index],".",true);
@@ -546,7 +545,8 @@ class OwnerPriceOperationService
             $units = app("UnitService")->getUnitMapping(["件","单","箱","m³","T","kg"]); //获取单位映射集
             $units = app("UnitService")->getUnitMapping(["件","单","箱","m³","T","kg"]); //获取单位映射集
             $exe = function ($mapping,$object,$detail)use($rule,$units,$owner,$discountIndex){
             $exe = function ($mapping,$object,$detail)use($rule,$units,$owner,$discountIndex){
                 $money = $this->matchItem($rule,$mapping,$object,$units,$owner,[$discountIndex=>true]);
                 $money = $this->matchItem($rule,$mapping,$object,$units,$owner,[$discountIndex=>true]);
-                if ($money>0)$detail->update(["work_fee"=>$money,"work_tax_fee"=>$money*($rule->taxRate->value/100)]);
+                $rate = $rule->taxRate ?: (Owner::query()->with("taxRate")->find($owner)->taxRate ?? null);
+                if ($money>0)$detail->update(["work_fee"=>$money,"work_tax_fee"=>$rate ? ($money*($rate->value/100)) : null]);
                 else $this->push(__METHOD__."->".__LINE__,"处理历史即时账单时发生匹配错误","账单主键:".$detail->id."; 错误代码".$money.";参数列表:".json_encode(array($rule, $owner, $discountIndex)));
                 else $this->push(__METHOD__."->".__LINE__,"处理历史即时账单时发生匹配错误","账单主键:".$detail->id."; 错误代码".$money.";参数列表:".json_encode(array($rule, $owner, $discountIndex)));
             };
             };
             if ($rule->operation_type=='入库'){
             if ($rule->operation_type=='入库'){

+ 72 - 0
app/Services/OwnerProcessSettlementBillService.php

@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Services;
+
+use App\Interfaces\SettlementBillDetailInterface;
+use App\OwnerFeeDetail;
+use App\Traits\ServiceAppAop;
+use Illuminate\Database\Eloquent\Builder;
+
+class OwnerProcessSettlementBillService implements SettlementBillDetailInterface
+{
+    use \App\Traits\SettlementBillServiceTrait;
+    const TYPE = '加工费';
+    use ServiceAppAop;
+
+    public function get(array $kvPairs): array
+    {
+        $details = $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->paginate($kvPairs['paginateParams']['paginate'] ?? 50);
+        $totalFee = $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->sum('work_fee');
+
+        return array($details,$totalFee);
+    }
+
+    public function getSql($owner_id, $counting_month): Builder
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return OwnerFeeDetail::query()
+            ->with(['process.processMethod'])
+            ->where('owner_id', $owner_id)
+            ->whereBetween('worked_at', [$start, $end])
+            ->where('outer_table_name','processes');
+    }
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        $result = array();
+        foreach ($details as $detail) {
+            $result[] = [
+                $detail->worked_at,
+                $detail->process->processMethod->name??'',
+                $detail->process->code??'',
+                $detail->operation_bill,
+                $detail->process->remark??'',
+                $detail->commodity_amount,
+                $detail->process->unit_price??'',
+                $detail->work_fee,
+            ];
+        }
+        return $result;
+    }
+
+    public function add(array $model)
+    {
+        // TODO: Implement add() method.
+    }
+
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return \Illuminate\Support\Facades\DB::table('owner_fee_details')
+            ->selectRaw("sum(work_fee) as fee,sum(work_tax_fee) as tax_fee")
+            ->where('owner_id', $owner_id)
+            ->whereBetween('created_at', [$start, $end])
+            ->first();
+    }
+
+}

+ 127 - 0
app/Services/OwnerProcurementSettlementBillService.php

@@ -0,0 +1,127 @@
+<?php
+
+namespace App\Services;
+
+use App\Interfaces\SettlementBillDetailInterface;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\OwnerMaterial;
+use App\Procurement;
+use App\Traits\ServiceAppAop;
+use Illuminate\Database\Eloquent\Builder;
+
+class OwnerProcurementSettlementBillService implements SettlementBillDetailInterface
+{
+
+
+    const  TYPE = '包材费';
+    use ServiceAppAop;
+    use \App\Traits\SettlementBillServiceTrait;
+
+    protected $modelClass = Procurement::class;
+    /**php
+     * @var $archiveService OwnerBillReportArchiveService
+     */
+    private $archiveService;
+
+    /**
+     * OwnerProcurementSettlementBillService constructor.
+     */
+    public function __construct()
+    {
+        $this->archiveService = app('OwnerBillReportArchiveService');
+    }
+
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        return $this->getSql($owner_id, $counting_month)->get()->sum('fee');
+    }
+
+    /**
+     *
+     * @param array $kvPairs
+     * @return array
+     */
+    public function get(array $kvPairs): array
+    {
+        if ($this->archiveService->isArchived($kvPairs['counting_month'], $kvPairs['owner_id'], $kvPairs['type']) == 1) {
+            $archived = $this->archiveService->get($kvPairs);
+            $details = collect($archived['information']['details']);
+            $total_fee = $archived['information']['total_fee'];
+        } else {
+            $details = $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->get();
+            $total_fee = $details->sum('fee');
+        }
+        return array($details, $total_fee);
+    }
+
+    public function getSql($owner_id, $counting_month): Builder
+    {
+        $ownerMaterialQuery = OwnerMaterial::query()->select('id')->where('owner_id', $owner_id);
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return Procurement::query()
+            ->selectRaw("id,owner_material_id,quantity,unit_price,ROUND(unit_price*quantity,2) as fee,created_at")
+            ->with('ownerMaterial:id,size,special,specification')
+            ->whereIn('owner_material_id', $ownerMaterialQuery)
+            ->whereBetween('created_at', [$start, $end]);
+    }
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        $result = [];
+        foreach ($details as $detail) {
+            $result[] = [
+                $detail->created_at,
+                $detail->ownerMaterial->special,
+                $detail->ownerMaterial->specification,
+                $detail->ownerMaterial->size,
+                $detail->quantity,
+                $detail->unit_price,
+                $detail->fee,
+            ];
+        }
+        return $result;
+    }
+
+    public function add(array $model)
+    {
+        // TODO: Implement add() method.
+    }
+
+    public function confirmBill($counting_month, $owner_id)
+    {
+        $billReport = OwnerBillReport::query()
+            ->select('storage_fee', 'id')
+            ->where('owner_id', $owner_id)
+            ->where('counting_month', $counting_month)
+            ->firstOr(function () {
+                return new OwnerBillReport();
+            });
+        list($details, $total_fee) = $this->get([
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this::TYPE,
+        ]);
+        OwnerBillReportArchive::query()->create([
+            'owner_bill_report_id' => $billReport->id ?? null,
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this::TYPE,
+            'archiver_id' => auth()->id(),
+            'archived_at' => now(),
+            'information' => [
+                'details' => $details,
+                'total_fee' => $total_fee,
+            ],
+        ]);
+        $this->confirmBillFeeTotal($counting_month, $owner_id);
+
+    }
+
+
+}

+ 61 - 0
app/Services/OwnerStoreFeeDetailService.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\OwnerStoreFeeDetail;
+use App\Traits\SettlementBillTrait;
+use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Builder;
+
+class OwnerStoreFeeDetailService
+{
+    use ServiceAppAop;
+    use \App\Traits\SettlementBillServiceTrait;
+
+    const TYPE = '入库费-明细';
+
+    protected $modelClass = OwnerStoreFeeDetail::class;
+
+    public function get(array $kvPairs): \Illuminate\Contracts\Pagination\LengthAwarePaginator
+    {
+        return $this->getSql($kvPairs['counting_month'], $kvPairs['owner_id'])->paginate($kvPairs['paginateParams']['paginate'] ?? 50);
+
+    }
+
+
+    /**
+     * @param $counting_month
+     * @param $owner_id
+     * @return Builder
+     */
+    public function getSql($counting_month, $owner_id): Builder
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return OwnerStoreFeeDetail::query()
+            ->with([
+                'ownerFeeDetail:id,worked_at',
+                'commodity:id,name',
+             ])
+            ->whereBetween('created_at', [$start, $end])
+            ->where('owner_id', $owner_id);
+    }
+
+    public function buildExport($details): array
+    {
+        $results = [];
+        foreach ($details as $detail) {
+            $results[] = [
+                $detail->ownerFeeDetail->worked_at ?? null,
+                $detail->work_name ?? null,
+                $detail->asn_code ?? null,
+                $detail->sku ?? null,
+                $detail->commodity->name ?? null,
+                $detail->amount ?? null,
+                $detail->unit_price ?? null,
+                $detail->fee ?? null,
+            ];
+        }
+        return $results;
+    }
+}

+ 172 - 0
app/Services/OwnerStoreFeeReportService.php

@@ -0,0 +1,172 @@
+<?php
+
+namespace App\Services;
+
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Traits\ServiceAppAop;
+use App\OwnerStoreFeeReport;
+use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\DB;
+
+class OwnerStoreFeeReportService implements \App\Interfaces\SettlementBillReportInterface
+{
+    const TYPE = '入库费-合计';
+
+    use ServiceAppAop;
+    use \App\Traits\SettlementBillServiceTrait;
+
+    protected $modelClass = OwnerStoreFeeReport::class;
+
+    /** @var  $archiveService OwnerBillReportArchiveService */
+    private $archiveService;
+    /** @var  $detailService OwnerStoreFeeDetailService */
+    private $detailService;
+
+
+    /**
+     * 生成报表数据
+     * 如果参数$counting_month为空 统计上一个月的
+     * 如果参数$counting_month为2021-01-01 则统计2021-01-01 -- 2021-01-31之间的数据
+     * @param null $counting_month 统计月份,默认统计上个月的 2021-05-01
+     */
+    public function recordReport($counting_month = null)
+    {
+        $this->detailService = app('OwnerStoreFeeDetailService');
+        if (is_null($counting_month)) {
+            //默认统计上个月的数据
+            $counting_month = now()->subMonth()->startOfMonth()->toDateString();
+        }
+        $this->reportDate = $counting_month;
+
+        $start = $this->reportDate;
+        $end = Carbon::parse($this->reportDate)->endOfMonth()->toDateString();
+        $details =
+            DB::table('owner_store_fee_details')
+                ->selectRaw("
+                DATE_FORMAT(owner_store_fee_details.created_at,'%Y-%m') as counting_month,
+                unit_id,
+                unit_price,
+                work_name,
+                sum(amount) as amounts ,
+                owner_store_fee_details.owner_id,
+                owner_fee_detail_id,
+                sum(owner_store_fee_details.fee) as fee
+                ")
+                ->whereBetween('owner_store_fee_details.created_at', [$start, $end])
+                ->groupBy(
+                    'counting_month',
+                    'owner_id',
+                    'unit_id',
+                    'unit_price',
+                    'work_name'
+                )
+                ->get();
+        $reports = [];
+        foreach ($details as $detail) {
+            $counting_month = Carbon::parse($detail->counting_month)->startOfMonth()->toDateString();
+            $ownerBillReport = OwnerBillReport::query()
+                ->selectRaw("id")
+                ->where('owner_id', $detail->owner_id)
+                ->where('counting_month', $counting_month)->first();
+            $reports[] = [
+                'owner_bill_report_id' => $ownerBillReport->id ?? null,
+                'owner_id' => $detail->owner_id,
+                'counting_month' => $counting_month,
+                'unit_id' => $detail->unit_id,
+                'unit_price' => $detail->unit_price,
+                'amount' => $detail->amounts,
+                'fee' => $detail->fee,
+                'work_name' => $detail->work_name,
+            ];
+        }
+        $reports_chunked = array_chunk($reports, 1000);
+        //保证幂等性 插入前删除该月的统计数据
+        OwnerStoreFeeReport::query()->where('counting_month', $counting_month)->delete();
+
+        foreach ($reports_chunked as $items) {
+            OwnerStoreFeeReport::query()->insertOrIgnore($items);
+        }
+    }
+
+    public function get(array $kvPairs): array
+    {
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $this->detailService = app('OwnerStoreFeeDetailService');
+        if ($this->archiveService->isArchived($kvPairs['counting_month'], $kvPairs['owner_id'], $kvPairs['type']) == 1) {
+            //查询存档数据
+            $archived = $this->archiveService->get($kvPairs);
+            $reports = collect($archived->information['reports']);
+            $totalAmount = $archived->information['totalAmount'];
+            $totalFee = $archived->information['totalFee'];
+            $owner_price_operation_fees = collect($archived->information['owner_price_operation_fees']);
+        } else {
+            $reports = $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->get();
+            $totalAmount = $reports->sum('amount');
+            $totalFee = number_format($reports->sum('fee'), 2);
+            $owner_price_operation_fees = OwnerStoreFeeReport::query()
+                ->selectRaw("sum(fee) as fee,work_name")
+                ->where('owner_id', $kvPairs['owner_id'])
+                ->where('counting_month', $kvPairs['counting_month'])
+                ->groupBy('work_name')->get();
+        }
+        return array($reports, $totalAmount, $totalFee, $owner_price_operation_fees);
+    }
+
+    /**
+     * @param $owner_id
+     * @param $counting_month
+     * @return Builder
+     */
+    public function getSql($owner_id, $counting_month): Builder
+    {
+        return OwnerStoreFeeReport::query()
+            ->with(['unit:id,name'])
+            ->where('owner_id', $owner_id)
+            ->where('counting_month', $counting_month);
+    }
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        // TODO: Implement buildExport() method.
+    }
+
+    public function confirmBill($counting_month, $owner_id)
+    {
+        $billReport = OwnerBillReport::query()
+            ->select('storage_fee', 'id')
+            ->where('owner_id', $owner_id)
+            ->where('counting_month', $counting_month)
+            ->firstOr(function () {
+                return new OwnerBillReport();
+            });
+        list($reports, $totalAmount, $totalFee, $owner_price_operation_fees) = $this->get([
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this::TYPE,
+        ]);
+        OwnerBillReportArchive::query()->create([
+            'owner_bill_report_id' => $billReport->id ?? null,
+            'owner_id' => $owner_id,
+            'counting_month' => $counting_month,
+            'type' => $this::TYPE,
+            'archiver_id' => auth()->id(),
+            'archived_at' => now(),
+            'information' => [
+                'reports' => $reports,
+                'totalAmount' => $totalAmount,
+                'totalFee' => $totalFee,
+                'owner_price_operation_fees' => $owner_price_operation_fees
+            ],
+        ]);
+        $this->confirmBillFeeTotal($counting_month, $owner_id);
+    }
+
+
+}

+ 97 - 0
app/Services/OwnerStoreOutFeeDetailService.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace App\Services;
+
+use App\Interfaces\SettlementBillDetailInterface;
+use App\OwnerFeeDetail;
+use App\Traits\ServiceAppAop;
+use App\OwnerStoreOutFeeDetail;
+use App\Traits\SettlementBillServiceTrait;
+use Illuminate\Contracts\Pagination\LengthAwarePaginator;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Collection;
+
+class OwnerStoreOutFeeDetailService implements SettlementBillDetailInterface
+{
+    const  TYPE = '出库费-明细';
+    use ServiceAppAop;
+    use SettlementBillServiceTrait;
+
+
+    protected $modelClass = OwnerStoreOutFeeDetail::class;
+
+    /**
+     * 详情的查询不管是否却认都是原始数据且分页
+     * @param array $kvPairs
+     * @return LengthAwarePaginator
+     */
+    public function get(array $kvPairs): LengthAwarePaginator
+    {
+        return $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->paginate($kvPairs['paginateParams']['paginate'] ?? 50);
+    }
+
+    public function getSql($owner_id, $counting_month): Builder
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return OwnerStoreOutFeeDetail::query()
+            ->with([
+                'commodity:id,name,sku',
+                'ownerFeeDetail:id,worked_at,operation_bill,work_fee'
+            ])
+            ->where('owner_id', $owner_id)
+            ->whereBetween('created_at', [$start, $end]);
+    }
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        $result = [];
+
+        foreach ($details as $detail) {
+            $result[] = [
+                $detail->ownerFeeDetail->worked_at,
+                $detail->work_name,
+                $detail->source_bill,
+                $detail->ownerFeeDetail->operation_bill,
+                $detail->sku,
+                $detail->barcode,
+                $detail->commodity->name ?? '',
+                $detail->amount,
+                $detail->unit_price,
+                $detail->price_remark,
+                $detail->fee,
+            ];
+        }
+        return $result;
+    }
+
+    public function add(array $model)
+    {
+        // TODO: Implement add() method.
+    }
+
+    /**
+     * 查询指定货主 月份 按照货主 计费模型汇总的 作业费(出入库费)和税费
+     * @param $owner_id
+     * @param $counting_month
+     * @return Builder[]|Collection
+     */
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return OwnerFeeDetail::query()
+            ->selectRaw("owner_price_operation_id,
+            sum(work_fee) as work_fee,
+            sum(work_tax_fee) as work_tax_fee
+             ")
+            ->where('owner_id', $owner_id)
+            ->whereBetween('created_at', [$start, $end])
+            ->groupBy('owner_id', 'owner_price_operation_id')
+            ->get();
+    }
+
+}

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