Browse Source

Merge branch 'master' into Haozi

# Conflicts:
#	app/Http/Controllers/TestController.php
haozi 4 years ago
parent
commit
db09b06023
100 changed files with 4815 additions and 817 deletions
  1. 4 1
      app/DischargeTask.php
  2. 61 0
      app/Events/SettlementBillCreateEvent.php
  3. 96 0
      app/Filters/RequirementFilters.php
  4. 0 39
      app/Http/Controllers/CacheShelfController.php
  5. 35 39
      app/Http/Controllers/ControlPanelController.php
  6. 1 1
      app/Http/Controllers/MenuController.php
  7. 153 0
      app/Http/Controllers/OwnerFeeTotalController.php
  8. 0 108
      app/Http/Controllers/OwnerLogisticFeeDetailController.php
  9. 17 0
      app/Http/Controllers/OwnerSundryFeeDetailsController.php
  10. 85 0
      app/Http/Controllers/OwnerWayBillFeeDetailController.php
  11. 24 0
      app/Http/Controllers/OwnerWaybillSettlementBillController.php
  12. 100 0
      app/Http/Controllers/RequirementController.php
  13. 85 0
      app/Http/Controllers/RequirementUserController.php
  14. 67 0
      app/Http/Controllers/SettlementBillExpressFeeDetailController.php
  15. 7 36
      app/Http/Controllers/SettlementBillExpressFeeReportController.php
  16. 66 0
      app/Http/Controllers/SettlementBillLogisticFeeController.php
  17. 66 0
      app/Http/Controllers/SettlementBillPackingMaterialFeeController.php
  18. 65 0
      app/Http/Controllers/SettlementBillProcessFeeController.php
  19. 26 47
      app/Http/Controllers/SettlementBillStorageFeeController.php
  20. 69 0
      app/Http/Controllers/SettlementBillStoreFeeDetailController.php
  21. 93 0
      app/Http/Controllers/SettlementBillStoreFeeReportController.php
  22. 58 0
      app/Http/Controllers/SettlementBillStoreOutFeeDetailController.php
  23. 87 0
      app/Http/Controllers/SettlementBillStoreOutFeeReportController.php
  24. 80 0
      app/Http/Controllers/SettlementBillSundryFeeController.php
  25. 62 0
      app/Http/Controllers/SettlementBillUnloadFeeController.php
  26. 54 0
      app/Http/Controllers/SettlementIndemnityFeeController.php
  27. 2 1
      app/Http/Controllers/StationController.php
  28. 3 1
      app/Http/Controllers/StorageController.php
  29. 95 199
      app/Http/Controllers/TestController.php
  30. 55 5
      app/Http/Controllers/WaybillController.php
  31. 17 11
      app/Http/Controllers/api/thirdPart/flux/WaybillController.php
  32. 2 1
      app/Http/Controllers/api/thirdPart/haiq/HaiRoboticsController.php
  33. 2 14
      app/Http/Controllers/api/thirdPart/haiq/LightController.php
  34. 39 0
      app/Http/Requests/RequirementRequest.php
  35. 31 0
      app/Interfaces/SettlementBillControllerInterface.php
  36. 32 0
      app/Interfaces/SettlementBillDetailInterface.php
  37. 41 0
      app/Interfaces/SettlementBillReportInterface.php
  38. 87 12
      app/Jobs/CacheShelfTaskJob.php
  39. 52 0
      app/Jobs/SettlementBillCountingTask.php
  40. 66 0
      app/Jobs/SettlementBillReportTask.php
  41. 37 0
      app/Listeners/SettlementBillCreateListener.php
  42. 1 0
      app/Owner.php
  43. 10 9
      app/OwnerBillReportArchive.php
  44. 12 2
      app/OwnerFeeDetail.php
  45. 45 0
      app/OwnerFeeTotal.php
  46. 31 2
      app/OwnerLogisticFeeDetail.php
  47. 15 1
      app/OwnerLogisticFeeReport.php
  48. 1 1
      app/OwnerPriceOperationItem.php
  49. 74 0
      app/OwnerStoreFeeDetail.php
  50. 46 0
      app/OwnerStoreFeeReport.php
  51. 69 0
      app/OwnerStoreOutFeeDetail.php
  52. 42 0
      app/OwnerStoreOutFeeReport.php
  53. 49 0
      app/OwnerWayBillFeeDetail.php
  54. 37 0
      app/Policies/RequirementPolicy.php
  55. 28 4
      app/Providers/AppServiceProvider.php
  56. 1 0
      app/Providers/AuthServiceProvider.php
  57. 3 0
      app/Providers/EventServiceProvider.php
  58. 79 0
      app/Requirement.php
  59. 18 0
      app/RequirementUser.php
  60. 24 49
      app/Services/CacheShelfService.php
  61. 8 10
      app/Services/DbOpenService.php
  62. 4 22
      app/Services/ForeignHaiRoboticsService.php
  63. 2 5
      app/Services/NewOrderCountingRecordService.php
  64. 21 7
      app/Services/OwnerBillReportArchiveService.php
  65. 74 0
      app/Services/OwnerDischargeTaskSettlementBillService.php
  66. 465 0
      app/Services/OwnerFeeTotalService.php
  67. 27 15
      app/Services/OwnerLogisticFeeDetailService.php
  68. 82 8
      app/Services/OwnerLogisticFeeReportService.php
  69. 72 0
      app/Services/OwnerProcessSettlementBillService.php
  70. 127 0
      app/Services/OwnerProcurementSettlementBillService.php
  71. 61 0
      app/Services/OwnerStoreFeeDetailService.php
  72. 172 0
      app/Services/OwnerStoreFeeReportService.php
  73. 97 0
      app/Services/OwnerStoreOutFeeDetailService.php
  74. 171 0
      app/Services/OwnerStoreOutFeeReportService.php
  75. 66 0
      app/Services/OwnerSundryFeeDetailService.php
  76. 13 0
      app/Services/OwnerWayBillFeeDetailService.php
  77. 92 0
      app/Services/OwnerWaybillSettlementBillService.php
  78. 13 0
      app/Services/RequirementService.php
  79. 13 0
      app/Services/RequirementUserService.php
  80. 71 40
      app/Services/SettlementBillsAreaFeeService.php
  81. 54 0
      app/Services/SettlementIndemnityFeeService.php
  82. 32 3
      app/Services/StationService.php
  83. 90 23
      app/Services/StationTaskBatchService.php
  84. 28 33
      app/Services/StationTaskMaterialBoxService.php
  85. 136 50
      app/Services/StorageService.php
  86. 12 3
      app/Station.php
  87. 4 0
      app/StationTaskCommodity.php
  88. 11 3
      app/TaskTransaction.php
  89. 70 0
      app/Traits/SettlementBillServiceTrait.php
  90. 57 0
      app/Traits/SettlementBillTrait.php
  91. 5 2
      app/Waybill.php
  92. 2 0
      config/api_logistic.php
  93. 2 0
      config/haiRou.php
  94. 0 7
      config/sync,php.php
  95. 12 0
      database/factories/OwnerBillTotalFactory.php
  96. 3 0
      database/factories/OwnerFeeDetailFactory.php
  97. 12 0
      database/factories/OwnerFeeTotalFactory.php
  98. 3 1
      database/factories/OwnerLogisticFeeDetailFactory.php
  99. 3 2
      database/factories/OwnerLogisticFeeReportFactory.php
  100. 21 0
      database/factories/OwnerPriceOperationItemFactory.php

+ 4 - 1
app/DischargeTask.php

@@ -61,5 +61,8 @@ class DischargeTask extends Model
         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;
 
 use App\Components\AsyncResponse;
-use App\Services\CacheShelfService;
 use App\Station;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\View\Factory;
 use Illuminate\Database\Eloquent\Builder;
-use Illuminate\Http\Request;
 use Illuminate\View\View;
 
 class CacheShelfController extends Controller
@@ -29,41 +27,4 @@ class CacheShelfController extends Controller
         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);
         $menus = app(CheckActiveMenuService::class)->activeMenus();
-        $owners=Owner::query()->whereIn('id',$ownerIds)->get();
+        $owners = Owner::query()->whereIn('id', $ownerIds)->get();
         $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)
@@ -49,8 +49,8 @@ class ControlPanelController extends Controller
         $orderCountingRecordService = app(NewOrderCountingRecordService::class);
         $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;
-        $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);
         return compact('orderCountingRecords');
     }
@@ -63,8 +63,8 @@ class ControlPanelController extends Controller
         $orderCountingRecordService = app(NewOrderCountingRecordService::class);
         $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;
-        $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);
         return compact('logisticsCountingRecords');
     }
@@ -112,12 +112,8 @@ class ControlPanelController extends Controller
         if (!$ownerIds) {
             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
         $start = Carbon::parse(request("start"));
-        $end   = Carbon::parse(request("end"));
+        $end = Carbon::parse(request("end"));
 
         //定义三个数组 空间换时间 避免结果集二次转换
         $title = []; //标题
         $data = []; //核心数据,二维数组
-        foreach (CarbonPeriod::create($start,$end) as $date){
+        foreach (CarbonPeriod::create($start, $end) as $date) {
             /** @var $date Carbon */
             $str = $date->format("Y-m-d");
             $data[] = $this->getTargetData($str);
@@ -140,26 +136,26 @@ class ControlPanelController extends Controller
         }
 
         //大于31天转换为月份显示
-        if ($end->diffInDays($start) > 31){
+        if ($end->diffInDays($start) > 31) {
             $title = [];
             $sign = []; //标记是否已被插入
             $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;
-                    $sign[$month] = count($dataTemp)-1;
-                }else{
+                    $sign[$month] = count($dataTemp) - 1;
+                } else {
                     $dataTemp[$sign[$month]]["total"] += $datum["total"];
                     $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;
         }
-        $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;
             $data[] = [
                 '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 = [];
         foreach ($data as $data_item) {
             $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)
     {
-        $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');
 
         $data = $service->get([
@@ -201,7 +197,7 @@ class ControlPanelController extends Controller
             'end_date' => $request->end,
             '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)
     {
-        if ($date == date("Y-m-d")){
+        if ($date == date("Y-m-d")) {
             $sql = <<<sql
 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,
@@ -221,13 +217,13 @@ AND order_packages.created_at >= '{$date} 00:00:00' GROUP BY date
 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"));
     }
 }

+ 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("route"))$update["route"] = request("route");
         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->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\Owner;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
 use App\OwnerSundryFeeDetail;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerSundryFeeDetailService;
+use App\Traits\SettlementBillTrait;
 use Illuminate\Http\Request;
 use App\Http\Requests\OwnerSundryFeeDetailRequest;
 use Oursdreams\Export\Export;
 
 class OwnerSundryFeeDetailsController extends Controller
 {
+    use SettlementBillTrait;
+
+
+
+    /** @var OwnerBillReportArchiveService $archiveService */
+    private $archiveService;
+
+    /** @var OwnerSundryFeeDetailService $service */
+    private $service;
+
     public function __construct()
     {
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        $this->service = app('OwnerSundryFeeDetailService');
         $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\OwnerLogisticFeeReportService;
 use App\Services\UserService;
+use App\Traits\SettlementBillTrait;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
 use Illuminate\Pagination\LengthAwarePaginator;
 use Oursdreams\Export\Export;
 
-class OwnerLogisticFeeReportController extends Controller
+class SettlementBillExpressFeeReportController extends Controller
 {
+    use SettlementBillTrait;
     /* @var OwnerLogisticFeeReportService $service */
     private $service;
     /* @var UserService $userService */
@@ -23,13 +25,6 @@ class OwnerLogisticFeeReportController extends Controller
     /** @var  $archiveService OwnerBillReportArchiveService */
     private $archiveService;
 
-    /**
-     * OwnerLogisticFeeReportController constructor.
-     */
-    public function __construct()
-    {
-        $this->middleware('auth');
-    }
 
 
     /**
@@ -55,11 +50,8 @@ class OwnerLogisticFeeReportController extends Controller
         $this->archiveService = app('OwnerBillReportArchiveService');
         $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)
@@ -126,32 +118,11 @@ class OwnerLogisticFeeReportController extends Controller
      * @param Request $request
      * @return RedirectResponse
      */
-    public function confirmBill(Request $request)
+    public function confirmBill(Request $request):RedirectResponse
     {
         $this->service = app('OwnerLogisticFeeReportService');
-        $this->archiveService = app('OwnerBillReportArchiveService');
         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', '确认成功');
     }
 }

+ 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\Request;
 use Oursdreams\Export\Export;
+use Tightenco\Collect\Support\Collection;
 
 /**
  * 结算管理-结算账单-仓储费
  * Class SettlementBillOwnerAreaFeeController
  * @package App\Http\Controllers
  */
-class SettlementBillOwnerAreaFeeController extends Controller
+class SettlementBillStorageFeeController extends Controller implements \App\Interfaces\SettlementBillControllerInterface
 {
+    use \App\Traits\SettlementBillTrait;
+
     /* @var $service SettlementBillsAreaFeeService */
     private $service;
     /** @var  $archiveService OwnerBillReportArchiveService */
     private $archiveService;
 
     /**
-     * SettlementBillOwnerAreaFeeController constructor.
+     * SettlementBillStorageFeeController constructor.
      */
     public function __construct()
-    {
-        $this->middleware('auth');
-    }
-
-    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);
-        $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,
             'counting_month' => $counting_month,
             '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)
     {
-        $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 = [];
         foreach ($areaReports as $areaReport) {
             $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['accounting_area'],
-                $price,
+                $areaReport['owner_storage_price_model']['price'],
                 $billReport['storage_fee'],
             ];
             $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['accounting_area'],
-                $price,
+                $areaReport['owner_storage_price_model']['price'],
+
                 $billReport['storage_fee'],
             ];
             $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['accounting_area'],
-                $price,
+                $areaReport['owner_storage_price_model']['price'],
                 $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)
+    {
+
+    }
+
+
+}

+ 2 - 1
app/Http/Controllers/StationController.php

@@ -64,7 +64,8 @@ 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[] = intval($count/$len*1000)/10;
+            $res[] = [$len,$count];
         }
         Cache::tags("loadBoxMonitor")->put($cacheKey,$res,1800);
         $this->success($res);

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

@@ -19,6 +19,7 @@ use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Foundation\Auth\AuthenticatesUsers;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Validator;
@@ -200,8 +201,9 @@ sql;
             ]);
             DB::commit();
             //亮灯
-            app("CacheShelfService")->lightUp($station->code,'2','1');
+            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"));

+ 95 - 199
app/Http/Controllers/TestController.php

@@ -157,219 +157,115 @@ class TestController extends Controller
     {
         return call_user_func([$this, $method], $request);
     }
-    public function test()
+    public function lightUp()
     {
-        $who= 'WAS'.(Auth::user() ? '-'.Auth::user()["name"] : '');
-        $time=Carbon::now()->toDateTimeString();
-        $asnno='ASN2107280001';
-       $db = DB::connection("oracle");
-       $db->transaction(function ()use($db,$time,$who,$asnno){
-           $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,$asnno]);
-//           $db->rollBack();
-           return true;
-       });
-    }
-    public function orderCreateBill()
+        app("CacheShelfService")->lightUp('HAIB1-02-02','3','2');
+    }
+    public function lightOff()
     {
-        $order = Order::query()->find(\request("id"));
-        $ser = new OrderService();
-        $ser->createInstantBill($order);
-        dd("order create bill success");
-    }
-    function mp(){
-        $stationTaskCommodities=StationTaskCommodity::query()->where('id',19942)->get();
-        StationTaskCommodity::query()
-            ->whereIn('id',data_get($stationTaskCommodities,'*.id')??[])
-            ->update(['status'=>'完成']);
-        $stationTaskMaterialBoxes=StationTaskMaterialBox::query()
-            ->whereIn('id', data_get($stationTaskCommodities, '*.station_task_material_box_id') ?? [])
-            ->get('material_box_id');
-        $storages= \App\Storage::query()->whereIn('commodity_id',data_get($stationTaskCommodities,'*.commodity_id')??[])
-            ->whereIn('material_box_id',data_get($stationTaskMaterialBoxes,'*.material_box_id')??[])
-            ->get();
-        foreach($storages as $storage){
-            $amountReducing=$stationTaskCommodities->where('material_box_id',$storage['material_box_id'])->first()['amount']??0;
-            $storage['amount']-=$amountReducing;
-            $storage->update();
-        }
-        return ['success'=>true];
+        $params = [
+            "areaCode" => "1004",
+            'locCode' => "HAIB1-02-02",
+            'PTLAction' => 0,
+        ];
+        $response = Http::post(config('api.haiq.storage.light'), $params);
+        return json_decode($response->body());
     }
-    function tailCustom($filepath, $lines = 1, $adaptive = true) {
-// Open file
-
-        $f = @fopen($filepath, "rb");
-
-        if ($f === false) return false;
-
-// Sets buffer size
-
-        if (!$adaptive) $buffer = 4096;
-
-        else $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096));
-
-// Jump to last character
-
-        fseek($f, -1, SEEK_END);
-
-// Read it and adjust line number if necessary
-
-// (Otherwise the result would be wrong if file doesn't end with a blank line)
-
-        if (fread($f, 1) != "\n") $lines -= 1;
-
-// Start reading
-
-        $output = '';
-
-        $chunk = '';
-
-// While we would like more
-
-        while (ftell($f) > 0 && $lines >= 0) {
-// Figure out how far back we should jump
-
-            $seek = min(ftell($f), $buffer);
-
-// Do the jump (backwards, relative to where we are)
-
-            fseek($f, -$seek, SEEK_CUR);
-
-// Read a chunk and prepend it to our output
-
-            $output = ($chunk = fread($f, $seek)) . $output;
-
-// Jump back to where we started reading
-
-            fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
-
-// Decrease our line counter
-
-            $lines -= substr_count($chunk, "\n");
-
-        }
-
-// While we have too many lines
-
-// (Because of buffer size we might have read too many)
-
-        /*while ($lines++ < 0) {
-// Find first newline and remove all text before that
-
-            $output = substr($output, strpos($output, "\n") + 1);
-
-        }*/
-// Close file and return
-        fclose($f);
-        return trim($output);
+    public function test3()
+    {
+       $a = Waybill::with("owner")->get();
 
+       dd($a->where("owner.code","TUCG2202012122323"));
     }
-
-    public function updateLaborRemark()
+    public function test1()
     {
-        $laborReports = LaborReport::query()->with(['remarks' => function ($query) {
-            return $query->whereNotNull('mark');
-        }])->get();
-        $updateParams = [[
-            'id', 'remark', 'updated_at'
-        ]];
-        $updated_at = Carbon::now()->toDateTimeString();
-        foreach ($laborReports as $laborReport) {
-            if ($laborReport->remarks) {
-                $updateParams[] = [
-                    'id' => $laborReport->id,
-                    'remark' => $laborReport->remarks->mark,
-                    'updated_at' => $updated_at,
-                ];
+        $batches = Batch::query()->where("code",\request("code"))->get();
+        DB::beginTransaction();
+        try {
+            $ids = [];
+            foreach ($batches as $b){
+                $ids[] = $b->id;
+            }
+            if (!$ids)dd("错误");
+            $tasks = StationTaskBatch::query()->whereIn("batch_id",$ids)->get();
+            foreach ($tasks as $task){
+                StationTaskMaterialBox::query()->where("station_task_batch_id",$task->id)->delete();
+                StationTask::query()->where("id",$task->station_task_id)->delete();
+                StationTaskChildren::query()->where("station_task_id",$task->station_task_id)->delete();
+                StationTaskCommodity::query()->where("station_task_id",$task->station_task_id)->delete();
+                StationTaskMaterialBox::query()->where("station_task_id",$task->station_task_id)->delete();
+                $task->delete();
             }
-        }
-        if (count($updateParams) > 1) {
-            app(BatchUpdateService::class)->batchUpdate('labor_reports', $updateParams);
-        }
-    }
 
-    function packageFromLog(Request $request)
-    { //x        $packagesBatch=Package::where('batch_number',$batch_number)->first();
-        ini_set('max_execution_time', 2500);
-        ini_set('memory_limit', '1526M');
-        $uploaded = 0;
-        $count = DB::table('logs')->where('operation', 'like', "%PackageController::new_%")
-            ->where('created_at', '>', "2020-06-08 15:46:00")
-            ->where('created_at', '<', "2020-06-08 15:47:00")
-            ->where('type', "request_new_")
-            ->count();
-        $requests = DB::table('logs')->where('operation', 'like', "%PackageController::new_%")
-            ->where('created_at', '>', "2020-06-08 15:46:00")
-            ->where('created_at', '<', "2020-06-08 15:47:00")
-            ->where('type', "request_new_")
-            ->get();
-        $requests->each(function ($request) use (&$uploaded) {
-            $requestJson = json_decode($request->description, true);
-            $response = Zttp::withHeaders(['content-type' => 'application/json',
-            ])->post('https://was.baoshi56.com/api/thirdPart/flux/package/new',
-                $requestJson
-            );
-            if ($response->json() && $response->json()['response'] && $response->json()['response']['flag'] == 'Y')
-                $uploaded += 1;
-        });
-        dd($uploaded . '/' . $count);
-    }
+            $stationTaskService = new StationTaskService();
+            $stationTaskBatchService = new StationTaskBatchService();
+            $stationTaskMaterialBoxService = new StationTaskMaterialBoxService();
+            $stationTaskCommodityService = new StationTaskCommodityService();
 
-    function setCache(Request $request)
-    {
-        $today = now();
-        Cache::put('storedTest', $today);
-        return "cacheing:'$today'<script>localStorage.setItem('storedTest','{$today}')</script>";
-    }
 
-    function getCache(Request $request)
-    {
-        $cache = Cache::get('storedTest');
-        return "cacheing get:'$cache'<script>document.write('<br>localStorage:'+localStorage.getItem('storedTest'))</script>";
-    }
+            $batches = collect($batches);
 
-    function hProcessed(Request $request)
-    {
-        app('ForeignHaiRoboticsService')->markBinProcessed(
-            '1',
-            'IDE0005714',
-            true,
-            "2021-56-24 05-03-15",
-            '',
-            true
-        );
-    }
+            $stationRuleBatchService = new StationRuleBatchService();
+           $batches_shouldProcess = collect($batches); //按规则过滤需要的波次
 
-    function hHasTaken(Request $request)
-    {
-        app('ForeignHaiRoboticsService')->taskUpdate(
-            301
-            , 1
-            , 0
-            , 'IDE0005714'
-        );
+            app('LogService')->log('海柔','assignTasks3',json_encode($batches_shouldProcess));
+            DB::transaction(function ()use($batches,&$batches_shouldProcess,&$stationTasks){
+                $stationTaskService = new StationTaskService();
+                $stationTaskBatchService = new StationTaskBatchService();
+                $stationTaskMaterialBoxService = new StationTaskMaterialBoxService();
+                $stationTaskCommodityService = new StationTaskCommodityService();
+                $stationTasks =  $stationTaskService->create($batches_shouldProcess->count()); //生成总任务
+                $stationTaskBatchService->createByBatches($batches_shouldProcess,$stationTasks); //注册波次任务
+                $stationTaskMaterialBoxService->createByBatches($batches_shouldProcess,$stationTasks); //注册料箱任务
+                $stationTaskCommodityService->createByBatches($batches_shouldProcess,$stationTasks); //注册商品任务
+            });
+            DB::commit();
+            dd("OK");
+        }catch (\Exception $e){
+            DB::rollBack();
+            dd($e);
+        }
     }
-
-    function hBatch(Request $request)
+    public function test()
     {
-        $a = [
-            new Batch(
-                [
-                    "id" => 91045,
-                    "code" => "W210325000388",
-                    "status" => "\u672a\u5904\u7406",
-                    "type" => null,
-                    "wms_type" => "09.[BAOSHI]\u622a\u5355\u6ce2\u6b21\u3010\u65e0\u5907\u6ce8\u3011",
-                    "wms_status" => "\u90e8\u5206\u6536\u8d27",
-                    "wms_created_at" => "0000-00-00 00:00:00",
-                    "created_at" => "2021-03-25T10:58:46.000000Z",
-                    "updated_at" => "2021-03-25T10:58:46.000000Z",
-                    "remark" => null,
-                    "owner_id" => "42"
-                ])
-        ];
-        app('BatchService')->assignTasks($a);
-        dd($a);
+        $stationTaskBatchService = new StationTaskBatchService();
+        $batch = Batch::query()->where("code",\request("code"))->first();
+        $batchTask=StationTaskBatch::query()->where("batch_id",$batch->id)->first();
+        $batchesFailed=$stationTaskBatchService->runMany(collect([$batchTask]));//执行波次任务
+        if($batchesFailed && $batchesFailed->isNotEmpty()){
+            return [
+                'success'=>false,
+                'errorMsg'=>'有部分失败波次:'.$batchesFailed->toJson()
+            ];
+        }
+        return ['success'=>true];
+    }
+    public function test2()
+    {
+        ini_set('max_execution_time', -1);
+        $s = StationTaskBatch::query()->with("stationTask.stationTaskMaterialBoxes")->find(2790);
+        dd($s);
+        $sql = <<<sql
+select * from order_commodities left join orders on order_id = orders.id
+where location like 'IDE%' and batch_id is not null and batch_id not in (78711,92315)
+and order_commodities.created_at > '2021-07-11 00:00:00'
+group by batch_id,commodity_id having (count(*)>1) order by order_commodities.created_at desc;
+sql;
+        $arr = DB::select(DB::raw($sql));
+        foreach ($arr as $a){
+            $sql = <<<sql
+select * from order_commodities where
+order_id in ( select id from orders where batch_id = (select batch_id from orders where id = {$a->order_id}))
+and location like 'IDE%' and order_commodities.created_at > '2021-07-01 00:00:00'
+sql;
+            $res = DB::select(DB::raw($sql));
+            $b = [];
+            foreach ($res as $r){
+                if (($b[$r->commodity_id] ?? false) && $b[$r->commodity_id]!=$r->location)dump($r);
+                $b[$r->commodity_id] = $r->location;
+            }
+        }
+        dd("OK");
     }
 
     function packageT(Request $request)

+ 55 - 5
app/Http/Controllers/WaybillController.php

@@ -177,11 +177,11 @@ class WaybillController extends Controller
             'user_id'=>Auth::id(),
         ]);
         //todo 若是德邦物流 请求API创建快递单号
-        $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']."】"  :'';
-        }
+//        $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??''));
     }
 
@@ -1036,6 +1036,7 @@ class WaybillController extends Controller
         $waybill = $waybills->first();
         $destroys = [];
         $owner = [$waybill->owner_id];
+        if (array_search($waybill->status,["未审核","已审核"])===false)$this->error("运单禁止合并");
         for ($i=1;$i<$waybills->count();$i++){
             //信息一致性校验
             $identical = ($waybill->order && ($waybills[$i]->order->consignee_name!=$waybill->order->consignee_name
@@ -1056,6 +1057,7 @@ class WaybillController extends Controller
             $waybill->warehouse_weight += (double)$waybills[$i]->warehouse_weight;
             $owner[] = $waybills[$i]->owner_id;
         }
+        if (strlen($waybill->source_bill)>191 || strlen($waybill->wms_bill_number)>191)$this->error("单号超长,无法合并");
         $owner = array_unique($owner);
         if (count($owner)>1)$waybill->merge_owner = implode(',',$owner);
         $waybill->update();
@@ -1067,4 +1069,52 @@ class WaybillController extends Controller
         ]);
         $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()));
         $errors=$this->validatorForNew($request->all())->errors();
         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));
             return response()->json(['response'=>['return'=>['returnFlag'=>'0','returnCode'=>'0001','returnDesc'=>'消息处理失败:Failure','resultInfo'=>'',
                 'errors'=>$errors]]])
@@ -63,6 +62,8 @@ class WaybillController extends Controller
             $owner=Owner::query()->where('code',$receiveInputting['CustomerID'])->first();
             if (!$owner){$owner=new Owner(['name'=>$receiveInputting['CustomerID'],'code'=>$receiveInputting['CustomerID']]);$owner->save();}
             $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();
             if ($bswasCustomer){
                 $origination=$bswasCustomer->address1;
@@ -73,11 +74,11 @@ class WaybillController extends Controller
             }
             $recipient_mobile=trim($receiveInputting['C_Tel1'],',');
             $waybill=new Waybill([
-                'type'=>isset($zfList[$receiveInputting['CarrierID']])&&$zfList[$receiveInputting['CarrierID']]?"直发车":"专线",
+                'type'=>$type,
                 'waybill_number'=>Uuid::uuid1(),
                 'owner_id'=>$owner->id,
                 'wms_bill_number'=>$receiveInputting['OrderNo']??'',
-                'origination'=>isset($origination)?$origination:"",
+                'origination'=>$origination ?? "",
                 'destination'=>$receiveInputting['C_Address1']??'',
                 'recipient'=>$receiveInputting['ConsigneeName']??'',
                 'recipient_mobile'=>$recipient_mobile??'',
@@ -109,15 +110,20 @@ class WaybillController extends Controller
                 'audit_stage'=>'创建',
                 '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));
             //回传FLUX
             $this->accomplishToWMS($waybill);

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

@@ -25,7 +25,8 @@ class HaiRoboticsController
             'errorMsg'=>'波次任务不能为空'
         ];
         $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()){
             return [
                 'success'=>false,

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

@@ -3,15 +3,11 @@
 
 namespace App\Http\Controllers\api\thirdPart\haiq;
 
-
-
-
 use App\Services\CacheShelfService;
 use App\Services\ForeignHaiRoboticsService;
 use App\Station;
 use App\Traits\TestableInstant;
 use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
 
 class LightController
 {
@@ -20,14 +16,6 @@ class LightController
 
     /** @var ForeignHaiRoboticsService $service */
     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}
@@ -51,12 +39,12 @@ class LightController
                 }
                 /** @var CacheShelfService $cacheShelfService */
                 $cacheShelfService = app(CacheShelfService::class);
-                $result =   $cacheShelfService->lightOffTask($request['locCode'],$request['PTLAction']);
+                $result =   $cacheShelfService->lightOffTask($request['locCode']);
                 $response['location']=$result['success']??'';
                 $response['errMsg']=$result['errMsg']??'';
                 return $response;
             case 'U型线拍灯':
-//                $this->foreignHaiRoboticsService->uLineLightPat($station);
+//                废弃此入口 U型线拍灯口迁移至 PickStationController:processed
         }
 
         return $response;

+ 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;
 
+use App\Components\ErrorPush;
 use App\Services\ForeignHaiRoboticsService;
+use App\Station;
 use App\StationTaskMaterialBox;
+use App\TaskTransaction;
 use Illuminate\Bus\Queueable;
 use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Foundation\Bus\Dispatchable;
 use Illuminate\Queue\InteractsWithQueue;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
 
 class CacheShelfTaskJob implements ShouldQueue
 {
-    use Dispatchable, InteractsWithQueue, Queueable;
+    use Dispatchable, InteractsWithQueue, Queueable, ErrorPush;
 
     protected $key;
     protected $count;
@@ -32,21 +36,92 @@ class CacheShelfTaskJob implements ShouldQueue
      * Execute the job.
      *
      * @return void
+     * @throws
      */
     public function handle()
     {
         /** @var ForeignHaiRoboticsService $service */
         $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);
+    }
+}

+ 1 - 0
app/Owner.php

@@ -4,6 +4,7 @@ namespace App;
 
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Support\Facades\Auth;
 

+ 10 - 9
app/OwnerBillReportArchive.php

@@ -27,15 +27,16 @@ class OwnerBillReportArchive extends Model
         'type' => [
             '' => 0,
             '仓储费' => 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;
 
-use App\Services\ProcessMethodService;
 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\HasOne;
+use Illuminate\Database\Eloquent\Relations\MorphTo;
 
 class OwnerFeeDetail extends Model
 {
@@ -77,4 +77,14 @@ class OwnerFeeDetail extends Model
     {
         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;
 
-    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
     {
@@ -22,11 +34,28 @@ class OwnerLogisticFeeDetail extends Model
 
     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
     {
         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;
 
-    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 function logistic(): BelongsTo

+ 1 - 1
app/OwnerPriceOperationItem.php

@@ -28,7 +28,7 @@ class OwnerPriceOperationItem extends Model
 
     public function unit()
     {   //单位
-        return $this->hasOne(Unit::class,"id","unit_id");
+        return $this->belongsTo(Unit::class);
     }
     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 == '已发布';
+    }
+}

+ 28 - 4
app/Providers/AppServiceProvider.php

@@ -4,10 +4,6 @@ namespace App\Providers;
 
 use App\Authority;
 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\Observers\AuthorityObserver;
 use App\Observers\MenuObserver;
@@ -148,11 +144,25 @@ use App\Services\OwnerLogisticFeeReportService;
 use App\Services\LogisticSyncRecordService;
 use App\Services\OwnerBillReportArchiveService;
 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\DeliveryTypeService;
 use App\Services\ErrorPushService;
 use App\Services\MaterialBoxModelService;
 use App\Services\HandInStorageService;
+use App\Services\RequirementService;
+use App\Services\RequirementUserService;
 
 class AppServiceProvider extends ServiceProvider
 {
@@ -296,7 +306,9 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OwnerAreaReportService', OwnerAreaReportService::class);
         app()->singleton('OwnerBillReportArchiveService',OwnerBillReportArchiveService::class);
         app()->singleton('OwnerBillReportService', OwnerBillReportService::class);
+        app()->singleton('OwnerDischargeTaskSettlementBillService',OwnerDischargeTaskSettlementBillService::class);
         app()->singleton('OwnerFeeDetailService', OwnerFeeDetailService::class);
+        app()->singleton('OwnerFeeTotalService',OwnerFeeTotalService::class);
         app()->singleton('OwnerLogisticFeeDetailService',OwnerLogisticFeeDetailService::class);
         app()->singleton('OwnerLogisticFeeReportService',OwnerLogisticFeeReportService::class);
         app()->singleton('OwnerMaterialService', OwnerMaterialService::class);
@@ -306,9 +318,18 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OwnerPriceLogisticService', OwnerPriceLogisticService::class);
         app()->singleton('OwnerPriceOperationItemService', OwnerPriceOperationItemService::class);
         app()->singleton('OwnerPriceOperationService', OwnerPriceOperationService::class);
+        app()->singleton('OwnerProcessSettlementBillService',OwnerProcessSettlementBillService::class);
+        app()->singleton('OwnerProcurementSettlementBillService',OwnerProcurementSettlementBillService::class);
         app()->singleton('OwnerReportService', OwnerReportService::class);
         app()->singleton('OwnerService', OwnerService::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('PackageStatisticsService', PackageStatisticsService::class);
         app()->singleton('PrintPartService',PrintPartService::class);
@@ -326,8 +347,11 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('RejectedBillItemService', RejectedBillItemService::class);
         app()->singleton('RejectedBillService', RejectedBillService::class);
         app()->singleton('RejectedService', RejectedService::class);
+        app()->singleton('RequirementService',RequirementService::class);
+        app()->singleton('RequirementUserService',RequirementUserService::class);
         app()->singleton('RoleService',RoleService::class);
         app()->singleton('SettlementBillsAreaFeeService',SettlementBillsAreaFeeService::class);
+        app()->singleton('SettlementIndemnityFeeService',SettlementIndemnityFeeService::class);
         app()->singleton('ShopService', ShopService::class);
         app()->singleton('StationCacheShelfGridService', StationCacheShelfGridService::class);
         app()->singleton('StationRuleBatchService', StationRuleBatchService::class);

+ 1 - 0
app/Providers/AuthServiceProvider.php

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

+ 3 - 0
app/Providers/EventServiceProvider.php

@@ -49,6 +49,9 @@ class EventServiceProvider extends ServiceProvider
         'App\Events\UpdateOrderPackageExceptionListenerEvent' => [//order_packages的数据的异常数据变更时
             '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;
+}

+ 24 - 49
app/Services/CacheShelfService.php

@@ -4,12 +4,10 @@ namespace App\Services;
 
 use App\Events\BroadcastToStation;
 use App\Exceptions\ErrorException;
-use App\MaterialBox;
 use App\Station;
-use App\StationTask;
-use App\StationTaskChildren;
 use App\StationTaskMaterialBox;
 use App\Traits\ServiceAppAop;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Http;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
@@ -45,30 +43,36 @@ class   CacheShelfService
     /**
      * 拍灯触发任务
      * @param $locCode
-     * @param $PTLAction
+     *
      * @return array|bool[]
      * @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("StorageService")->checkStorage($station)){
+            $result = app("StorageService")->checkStorage($station);
+            if ($result===false){//任务存在且失败 红灯
                 $this->lightUp($station->code,'0','1',["title"=>"上架失败,联系管理员"]);
                 return ['success' => false,'errMsg' => '上架任务失败'];
             };
+            if ($result===true){//任务存在且成功 绿灯
+                $this->lightUp($station->code);
+                return ['success' => true];
+            }
         }
         try {
             $bool = $this->putBinToStore($station);                         // 推送任务
             if ($bool) {
                 LogService::log(__CLASS__, 'lightOffTask', 'code' . ' true' . $locCode . json_encode($station));
                 return ['success' => true];
-            } else {
-                return ['success' => false, 'errMsg' => '机器人推送失败'];
-            }
+            }else return ['success' => false, 'errMsg' => '机器人推送失败'];
         } catch (ErrorException $e) {
             LogService::log(__FUNCTION__, '缓存架推送任务失败', json_encode($e->getMessage()));
             return ['success' => false, 'errMsg' => $e->getMessage()];
@@ -78,50 +82,21 @@ class   CacheShelfService
     /**
      * 推任务至海柔机器人
      * @param  $station
-     * @return array
+     * @return bool
      * @throws ErrorException
      * @throws \Exception
      */
-    public function putBinToStore($station): array
+    public function putBinToStore($station): bool
     {
         $this->instant($this->foreignHaiRoboticsService, 'ForeignHaiRoboticsService');
         $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 */
-        $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];
-    }
+        $stationTaskMaterialBox = app("StorageService")->createWarehousingTask($this->stationService->getStation_byType('立库')["id"],$station->materialBox->id);
 
-    /**
-     * 缓存架和料箱的绑定
-     * @param $stationCode
-     * @param $materialBoxCode
-     * @return array
-     */
-    public function bindMaterialBox($stationCode, $materialBoxCode): array
-    {
-        return ['success' => false,'message' => "接口废弃"];
+        return $this->foreignHaiRoboticsService->putBinToStore_fromCacheShelf($stationTaskMaterialBox, $station);
     }
 
     /**
@@ -141,8 +116,8 @@ class   CacheShelfService
             "detail03" => "",
             "qrCode" => "",
             "qty00" => "",
-            "qty01" => 0,
-            "qty02" => 0,
+            "qty01" => "",
+            "qty02" => "",
             "title" => '',
             "uomDesc01" => "",
             "uomDesc02" => ""

+ 8 - 10
app/Services/DbOpenService.php

@@ -21,7 +21,7 @@ class DbOpenService
      * 创建德邦订单,生成快递单号
      * @param array $params
      */
-    public function getDbOrderNo($params = [])
+    public function getDbOrderNo(array $params = []):array
     {
         //获取系统无快递单号订单信息
         $order_info = Waybill::query()
@@ -33,7 +33,6 @@ class DbOpenService
             ->first();
         //请求德邦API 生成新订单
         $model = new OrderLogistic();
-        $uri = "http://dpsanbox.deppon.com/sandbox-web/dop-standard-ewborder/createOrderNotify.action";
         $header = [
             'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
             "Accept" => "application/json"
@@ -108,18 +107,18 @@ class DbOpenService
                         'key' => ''
                     ]
                 ];
-                $param = json_encode($data, true);
+                $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($uri, $dd, $header);
+                $return = httpPost(config('api_logistic.DB.prod.uri')['create_order'], $dd, $header);
                 unset($data);
+                $id = $params['id'];
+                $order_no = $order_info->wms_bill_number;
                 if (array_key_exists('result', $return)) {
                     //请求成功  快递单号 $return['mailNo']   请求编号 $return['uniquerRequestNumber']
                     //返回日志记录
-                    $id = $params['id'];
-                    $order_no = $order_info->wms_bill_number;
                     $mail_no = $return['mailNo']??'';
                     $add_data = [
                         'order_id' => $order_info->order->id,
@@ -159,10 +158,9 @@ class DbOpenService
      * @param array $params
      * @return array
      */
-    public function getOrderStatus($params = [])
+    public function getOrderStatus(array $params = []):array
     {
         if ( ($params['mailNo']??'') == '') return ['code' => 0 , 'msg' => '德邦运单号不能为空'];
-        $uri = "http://dpsanbox.deppon.com/sandbox-web/standard-order/newTraceQuery.action";
         $header = [
             'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
             "Accept" => "application/json"
@@ -170,12 +168,12 @@ class DbOpenService
         $data = [
             'mailNo' => $params['mailNo']??''
         ];
-        $param = json_encode($data, true);
+        $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($uri, $dd, $header);
+        $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']];
         }

+ 4 - 22
app/Services/ForeignHaiRoboticsService.php

@@ -22,7 +22,6 @@ use App\Traits\ServiceAppAop;
 class ForeignHaiRoboticsService
 {
     use ServiceAppAop;
-//    protected $modelClass=ForeignHaiRobotics::class;
 
     /** @var  $stationTaskMaterialBoxService StationTaskMaterialBoxService */
     private $stationTaskMaterialBoxService;
@@ -142,24 +141,21 @@ class ForeignHaiRoboticsService
      * @param string $groupIdPrefix
      * @param string $mode
      * @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(
             $taskMaterialBoxes,
             $mode,
             null,
             $toLocations,
-            $groupIdPrefix
+            $groupIdPrefix,
+            $priority
         );
         return $this->controlHaiRobot($dataToPost,$taskMaterialBoxes,$mode);
     }
 
-    public function moveBin(){
-
-    }
-
     public function markBinProcessed(
         $workStation,
         $binCode,
@@ -184,17 +180,9 @@ class ForeignHaiRoboticsService
                 throw new ErrorException('海柔任务失败:'.$exception);
             LogService::log('海柔请求','markBinProcessed1.3',
                 $failed);
-//            if($NotInPlan
-//                =!$is_in_plan)
-//                throw new ErrorException('海柔认为是计划外的料箱:'.$exception);
-
-            LogService::log('海柔请求','markBinProcessed1.4',
-                '$NotInPlan');
 
             $materialBox=
                 $this->materialBoxService->get(['code'=>$binCode])->first();
-            LogService::log('海柔请求','markBinProcessed1.5',
-                json_encode($materialBox));
             /** @var StationTaskMaterialBox $stationTaskMaterialBox */
             $stationTaskMaterialBox
                 =(function()use($materialBox){
@@ -206,13 +194,9 @@ class ForeignHaiRoboticsService
                         ->orderBy('id','desc')
                     ->first();
             })();
-            LogService::log('海柔请求','markBinProcessed1.6',
-                json_encode($stationTaskMaterialBox).'|'.$binCode);
             if(!$stationTaskMaterialBox){
                 throw new ErrorException($binCode.'该料箱没有安排在处理队列中.');
             }
-            LogService::log('海柔请求','markBinProcessed1.7',
-                json_encode($stationTaskMaterialBox).'|'.$binCode);
 
             DB::transaction(function ()use($stationTaskMaterialBox,$binCode){
                 $stationTaskMaterialBox_next=
@@ -235,8 +219,6 @@ class ForeignHaiRoboticsService
                         json_encode($stationTaskMaterialBox['stationTaskBatch']).'|'.$binCode);
                     $stationTaskMaterialBox->loadMissing('stationTaskBatch');
                     $this->stationTaskBatchService->markProcessed($stationTaskMaterialBox['stationTaskBatch']);
-                    LogService::log('海柔请求','markBinProcessed1.82',
-                        json_encode($stationTaskMaterialBox['stationTaskBatch']).'|'.$binCode);
                     $this->stationTaskService->markProcessed($stationTaskMaterialBox['stationTask']);
                 }
                 $this->storeBox($stationTaskMaterialBox)

+ 2 - 5
app/Services/NewOrderCountingRecordService.php

@@ -487,9 +487,6 @@ class NewOrderCountingRecordService
         return $ttl;
     }
 
-
-    //TODO 控制台重构
-
     public function getWareHouseRecordsApi($start, $end, $ownerIds): array
     {
         $orderCountingRecords = OrderCountingRecord::query()
@@ -670,11 +667,11 @@ class NewOrderCountingRecordService
             $end = now()->subMonth()->endOfDay();
         }
         $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")
             ->whereBetween('date_target', [$startDate, $endDate])
             ->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) {
                 $insertData = [];
                 foreach ($records as $record) {

+ 21 - 7
app/Services/OwnerBillReportArchiveService.php

@@ -2,8 +2,6 @@
 
 namespace App\Services;
 
-use App\OwnerAreaReport;
-use App\OwnerBillReport;
 use App\Traits\ServiceAppAop;
 use App\OwnerBillReportArchive;
 use Illuminate\Database\Eloquent\Builder;
@@ -23,7 +21,7 @@ class OwnerBillReportArchiveService
      */
     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);
     }
 
@@ -31,12 +29,11 @@ class OwnerBillReportArchiveService
      * @param $counting_month
      * @param $owner_id
      * @param $type
-     * @return int
+     * @return int 1 已确认 2 未确认
      */
     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)
     {
-//枚举转换
+        //枚举转换
         if (is_string($type)) {
             $type = OwnerBillReportArchive::$enums['type'][$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\Traits\ServiceAppAop;
 use App\OwnerLogisticFeeDetail;
+use App\Traits\SettlementBillServiceTrait;
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Pagination\LengthAwarePaginator;
-use Illuminate\Support\Collection;
 
-class OwnerLogisticFeeDetailService
+class OwnerLogisticFeeDetailService implements \App\Interfaces\SettlementBillDetailInterface
 {
+    use SettlementBillServiceTrait;
     const TYPE = '快递费-明细';
 
     use ServiceAppAop;
@@ -22,20 +23,15 @@ class OwnerLogisticFeeDetailService
      */
     protected $modelClass = OwnerLogisticFeeDetail::class;
 
-    //插入数据 ServiceAppAop的 insert 方法 支持批量
 
     /**
      * 根据货主查询 和时间段查询
-     * @param string $owner_id
-     * @param string $start
-     * @param string $end
-     * @param $paginateParams
+     * @param array $kvPairs
      * @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);
         return new LengthAwarePaginator(
             $items,
@@ -65,13 +61,11 @@ class OwnerLogisticFeeDetailService
     }
 
     /**
-     * @param string $owner_id
-     * @param string $start
-     * @param string $end
      * @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([
             'ownerFeeDetail:id,province,weight,logistic_fee',
             'ownerFeeDetailLogistic:id,weight,logistic_fee,logistic_bill',
@@ -97,9 +91,27 @@ class OwnerLogisticFeeDetailService
                 'weight' => $ownerLogisticFeeDetail->ownerFeeDetailLogistic->weight ?? $ownerLogisticFeeDetail->ownerFeeDetail->weight ?? '0.00',//重量
                 'initial_weight_price' => $ownerLogisticFeeDetail->initial_weight_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;
     }
+
+    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;
 
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
 use App\OwnerLogisticFeeDetail;
 use App\Traits\ServiceAppAop;
 use App\OwnerLogisticFeeReport;
@@ -10,10 +12,12 @@ use Illuminate\Contracts\Pagination\LengthAwarePaginator;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 
-class OwnerLogisticFeeReportService
+class OwnerLogisticFeeReportService implements \App\Interfaces\SettlementBillReportInterface
 {
     const TYPE = '快递费-合计';
+
     use ServiceAppAop;
+    use \App\Traits\SettlementBillServiceTrait;
 
     protected $modelClass = OwnerLogisticFeeReport::class;
 
@@ -21,6 +25,44 @@ class OwnerLogisticFeeReportService
     /** @var  $archiveService OwnerBillReportArchiveService */
     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为空 统计上一个月的
@@ -40,7 +82,20 @@ class OwnerLogisticFeeReportService
 
 
         $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])
             ->groupBy('initial_weight', 'initial_weight_price', 'additional_price', 'additional_weight', 'logistic_id', 'province', 'counted_date', 'owner_id')
             ->get();
@@ -57,10 +112,14 @@ class OwnerLogisticFeeReportService
                 'additional_weight' => $ownerLogisticFeeDetail->additional_weight,
                 'additional_price' => $ownerLogisticFeeDetail->additional_price,
                 '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,
             ];
         }
+        //保证接口幂等性 删除统计月的数据
+        OwnerLogisticFeeReport::query()->where('counted_date', $counting_month)->delete();
+
         OwnerLogisticFeeReport::query()->insertOrIgnore($ownerLogisticFeeReportArray);
     }
 
@@ -71,7 +130,7 @@ class OwnerLogisticFeeReportService
      * @param $paginateParams
      * @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)
             ->paginate($paginateParams['paginate'] ?? 50);
@@ -81,12 +140,14 @@ class OwnerLogisticFeeReportService
     {
         $this->archiveService = app('OwnerBillReportArchiveService');
         if ($this->archiveService->isArchived($kvPairs['counting_month'], $kvPairs['owner_id'], $kvPairs['type']) == 1) {
+            //查询存档数据
             $archived = $this->archiveService->get($kvPairs);
-            $reports =collect($archived->information['reports']);
+
+            $reports = collect($archived->information['reports']);
             $recordTotal = $archived->information['recordTotal'];
         } else {
             $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);
     }
@@ -126,10 +187,10 @@ class OwnerLogisticFeeReportService
 
     /**
      * @param $owner_id
-     * @param string $counting_month
+     * @param  $counting_month
      * @return Builder
      */
-    public function getSql($owner_id, string $counting_month): Builder
+    public function getSql($owner_id, $counting_month): Builder
     {
         return OwnerLogisticFeeReport::query()
             ->with('logistic:id,name')
@@ -138,4 +199,17 @@ class OwnerLogisticFeeReportService
             ->orderByDesc('logistic_id')
             ->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();
+    }
 }

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

+ 171 - 0
app/Services/OwnerStoreOutFeeReportService.php

@@ -0,0 +1,171 @@
+<?php
+
+namespace App\Services;
+
+use App\Interfaces\SettlementBillReportInterface;
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\OwnerFeeDetail;
+use App\OwnerStoreFeeReport;
+use App\OwnerStoreOutFeeDetail;
+use App\Traits\ServiceAppAop;
+use App\OwnerStoreOutFeeReport;
+use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\DB;
+
+class OwnerStoreOutFeeReportService implements SettlementBillReportInterface
+{
+    const TYPE = '出库费-合计';
+
+    use ServiceAppAop;
+
+    use \App\Traits\SettlementBillServiceTrait;
+
+    protected $modelClass = OwnerStoreOutFeeReport::class;
+    /** @var $detailService OwnerBillReportArchiveService */
+    private $archiveService;
+
+    /** @var $detailService OwnerStoreOutFeeDetailService */
+    private $detailService;
+
+    public function recordReport($counting_month = null)
+    {
+        $this->detailService = app('OwnerStoreOutFeeDetailService');
+        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 = OwnerStoreOutFeeDetail::query()
+            ->selectRaw("
+                DATE_FORMAT(owner_store_out_fee_details.created_at,'%Y-%m') as counting_month,
+                step,
+                unit_id,
+                unit_price,
+                sum(amount) as  amount ,
+                sum(fee) as  fee ,
+                owner_id,
+                work_name
+            ")
+            ->whereBetween('created_at', [$start, $end])
+            ->groupBy(
+                'counting_month',
+                'step',
+                'unit_id',
+                'unit_price',
+                'owner_id',
+                '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,
+                'step' => $detail->step,
+                'unit_id' => $detail->unit_id,
+                'unit_price' => $detail->unit_price,
+                'amount' => $detail->amount,
+                'fee' => $detail->fee,
+                'work_name' => $detail->work_name,
+            ];
+        }
+
+        //保证幂等性 插入前删除该月的统计数据
+        OwnerStoreOutFeeReport::query()->where('counting_month', $counting_month)->delete();
+
+        foreach (array_chunk($reports, 1000) as $reports_chunked) {
+            OwnerStoreOutFeeReport::query()->insertOrIgnore($reports_chunked);
+        }
+    }
+
+    public function getSql($owner_id, $counting_month): Builder
+    {
+        // TODO: Implement getSql() method.
+    }
+
+
+    public function buildExport($details): array
+    {
+        // TODO: Implement buildExport() method.
+    }
+
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    function get(array $kvPairs)
+    {
+        $this->archiveService = app('OwnerBillReportArchiveService');
+        list($start, $end) = $this->getStartAndEnd($kvPairs['counting_month']);
+        if ($this->archiveService->isArchived($kvPairs['counting_month'], $kvPairs['owner_id'], $kvPairs['type']) == 1) {
+            //查询存档数据
+            $archived = $this->archiveService->get($kvPairs);
+            $reports = collect($archived->information['reports']);
+            $work_name_fee_total = collect($archived->information['work_name_fee_total']);
+            $fee_total = $archived->information['fee_total'];
+        } else {
+            $reports = OwnerStoreOutFeeReport::query()
+                ->with(['unit:id,name'])
+                ->where('owner_id', $kvPairs['owner_id'])
+                ->where('counting_month', $kvPairs['counting_month'])
+                ->get();
+
+            $work_name_fee_total = OwnerStoreOutFeeReport::query()
+                ->selectRaw("
+                    sum(fee) as fee,
+                    work_name
+                ")
+                ->where('counting_month' , $kvPairs['counting_month'])
+                ->where('owner_id', $kvPairs['owner_id'])
+                ->groupBy('work_name')
+                ->get();
+            $fee_total = $work_name_fee_total->sum('fee');
+        }
+        return array($reports, $work_name_fee_total, $fee_total);
+    }
+
+    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, $work_name_fee_total, $fee_total) = $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,
+                'work_name_fee_total' => $work_name_fee_total,
+                'fee_total' => $fee_total,
+            ],
+        ]);
+        $this->confirmBillFeeTotal($counting_month, $owner_id);
+
+    }
+
+
+}

+ 66 - 0
app/Services/OwnerSundryFeeDetailService.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\OwnerSundryFeeDetail;
+use Illuminate\Contracts\Pagination\LengthAwarePaginator;
+use Illuminate\Database\Eloquent\Builder;
+
+class OwnerSundryFeeDetailService implements \App\Interfaces\SettlementBillReportInterface
+{
+    use ServiceAppAop;
+    use \App\Traits\SettlementBillServiceTrait;
+
+
+    protected $modelClass = OwnerSundryFeeDetail::class;
+    /** @var OwnerBillReportArchiveService $archiveService */
+    private $archiveService;
+    const TYPE = '杂项费';
+
+    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 OwnerSundryFeeDetail::query()
+            ->with(['owner', 'logistic'])
+            ->where('owner_id', $owner_id)
+            ->whereBetween('created_at', [$start, $end]);
+    }
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        // TODO: Implement buildExport() method.
+    }
+
+    public function add(array $model)
+    {
+        // TODO: Implement add() method.
+    }
+
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return OwnerSundryFeeDetail::query()
+            ->selectRaw("type,sum(fee) as fee")
+            ->where('owner_id', $owner_id)
+            ->whereBetween('created_at', [$start, $end])
+            ->groupBy('type')
+            ->get();
+    }
+
+    public function recordReport($counting_month = null)
+    {
+        // TODO: Implement recordReport() method.
+    }
+
+}

+ 13 - 0
app/Services/OwnerWayBillFeeDetailService.php

@@ -0,0 +1,13 @@
+<?php 
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\OwnerWayBillFeeDetail;
+
+class OwnerWayBillFeeDetailService
+{
+    use ServiceAppAop;
+    protected $modelClass=OwnerWayBillFeeDetail::class;
+
+}

+ 92 - 0
app/Services/OwnerWaybillSettlementBillService.php

@@ -0,0 +1,92 @@
+<?php
+
+namespace App\Services;
+
+use App\OwnerFeeDetail;
+use App\Traits\ServiceAppAop;
+use App\Waybill;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\DB;
+
+class OwnerWaybillSettlementBillService implements \App\Interfaces\SettlementBillDetailInterface
+{
+    use ServiceAppAop;
+    use \App\Traits\SettlementBillServiceTrait;
+
+    const TYPE = '物流费';
+
+
+    public function get(array $kvPairs)
+    {
+        return $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->paginate($kvPairs['paginateParams']['paginate'] ?? 50);
+    }
+
+
+    /**
+     * @param $owner_id
+     * @param $counting_month
+     * @return Builder
+     */
+    public function getSql($owner_id, $counting_month): Builder
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        $ownerFeeDetailIdsQuery = OwnerFeeDetail::query()
+            ->select('id')
+            ->with('ownerPriceLogistic')
+            ->where('owner_id', $owner_id)
+            ->where('outer_table_name', 'waybills')
+            ->whereBetween('created_at', [$start, $end]);
+        return Waybill::query()->whereIn('id', $ownerFeeDetailIdsQuery)
+            ->with(['ownerWayBillFeeDetail.ownerFeeDetail', 'logistic', 'warehouseWeightUnit', 'originationCity', 'destinationCity']);
+    }
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        $results = [];
+        foreach ($details as $detail) {
+            $results[] = [
+                $detail->logistic->name ?? '',
+                $detail->order_id ?? '',
+                $detail->recipient ?? '',
+                $detail->recipient_mobile ?? '',
+                $detail->warehouse_weight ?? '',
+                $detail->warehouseWeightUnit->name ?? '',
+                $detail->ownerWayBillFeeDetail->step ?? '',
+                $detail->ownerWayBillFeeDetail->ownerFeeDetail->province ?? '',
+                $detail->destination_city->name ?? '',
+                $detail->ownerWayBillFeeDetail->price ?? '',
+                $detail->ownerWayBillFeeDetail->delivery_fee ?? '',
+                $detail->pick_up_fee ?? '',
+                $detail->ownerWayBillFeeDetail->fuel_fee ?? '',
+                $detail->ownerWayBillFeeDetail->service_fee ?? '',
+                $detail->other_fee ?? '',
+                $detail->dispatch_remark ?? '',
+                $detail->ownerWayBillFeeDetail->originate_fee ?? '',
+                $detail->ownerWayBillFeeDetail->originate_count ?? '',
+                $detail->ownerWayBillFeeDetail->ownerFeeDetail->logistic_fee ?? '',
+            ];
+        }
+        return $results;
+    }
+
+    public function add(array $model)
+    {
+        // TODO: Implement add() method.
+    }
+
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return DB::table('owner_way_bill_fee_details')
+            ->selectRaw("sum(owner_fee_details.logistic_fee) as fee,sum(owner_fee_details.logistic_tax_fee) as tax_fee")
+            ->leftJoin('owner_fee_details', 'owner_way_bill_fee_details.owner_fee_detail_id', '=', 'owner_fee_details.id')
+            ->whereBetween('owner_way_bill_fee_details.created_at', [$start, $end])
+            ->where('owner_fee_details.owner_id',$owner_id)
+            ->first();
+    }
+}

+ 13 - 0
app/Services/RequirementService.php

@@ -0,0 +1,13 @@
+<?php 
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\Requirement;
+
+class RequirementService
+{
+    use ServiceAppAop;
+    protected $modelClass=Requirement::class;
+
+}

+ 13 - 0
app/Services/RequirementUserService.php

@@ -0,0 +1,13 @@
+<?php 
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\RequirementUser;
+
+class RequirementUserService
+{
+    use ServiceAppAop;
+    protected $modelClass=RequirementUser::class;
+
+}

+ 71 - 40
app/Services/SettlementBillsAreaFeeService.php

@@ -4,9 +4,10 @@ namespace App\Services;
 
 use App\OwnerAreaReport;
 use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
 use App\Traits\ServiceAppAop;
 
-class SettlementBillsAreaFeeService
+class SettlementBillsAreaFeeService implements \App\Interfaces\SettlementBillReportInterface
 {
     /** @var $archiveService  OwnerBillReportArchiveService */
     private $archiveService;
@@ -14,46 +15,27 @@ class SettlementBillsAreaFeeService
 
     use ServiceAppAop;
 
-    /**
-     * @param $year
-     * @param $month
-     * @param $owner_id
-     * @return array
-     */
-    public function getRequestParams($year, $month, $owner_id): array
-    {
-        $this->service = app('OwnerLogisticFeeReportService');
-        $this->userService = app('UserService');
-        $permittingOwnerIds = $this->userService->getPermittingOwnerIds(auth()->user());
-        if (is_null($year)) {
-            $year = now()->subMonth()->year;
-        }
-        if (is_null($month)) {
-            $month = now()->subMonth()->month;
-        }
-        $counting_month = $year . '-' . $month . '-' . '01';
-        if (is_null($owner_id)) {
-            $owner_id = $permittingOwnerIds[0];
-        }
-        return array($permittingOwnerIds, $counting_month, $owner_id);
-    }
+    use \App\Traits\SettlementBillServiceTrait;
 
     /**
-     * @param $owner_id
-     * @param $counting_month
+     * @param array $kvPairs
      * @return array
      */
-    public function get($owner_id, $counting_month): array
+    public function get(array $kvPairs): array
     {
         $this->archiveService = app('OwnerBillReportArchiveService');
-        $archived = $this->archiveService->getSql(\Carbon\Carbon::parse($counting_month)->toDateString(), $owner_id, \App\OwnerBillReportArchive::$enums['type']['仓储费'])->first();
-        if ($archived ?? false) {
+        $counting_month = $kvPairs['counting_month'];
+        $owner_id = $kvPairs['owner_id'];
+        if ($this->archiveService->isArchived($kvPairs['counting_month'], $kvPairs['owner_id'], $kvPairs['type']) == 1) {
+            $archived = $this->archiveService->get($kvPairs);
             $areaReports = collect($archived->information['areaReports']);
             $billReport = collect($archived->information['billReport']);
-            $price = $archived->information['price'];
         } else {
             $areaReports = OwnerAreaReport::query()
-                ->with('ownerStoragePriceModel:id,using_type,price')
+                ->with(['ownerStoragePriceModel' => function ($query) {
+                    $query->selectRaw("id,using_type,price,unit_id,unit_id,time_unit_id,name,minimum_area")
+                        ->with(['unit:id,name', 'timeUnit:id,name']);
+                }])
                 ->where('owner_id', $owner_id)
                 ->where('counting_month', $counting_month)
                 ->get();
@@ -64,15 +46,64 @@ class SettlementBillsAreaFeeService
                 ->firstOr(function () {
                     return new OwnerBillReport();
                 });
-            $totalArea = $areaReports->reduce(function ($carry, $areaReport) {
-                return $carry + $areaReport->accounting_area;
-            }, 0);
-            try {
-                $price = number_format(($billReport->storage_fee ?? 0) / $totalArea, 3);
-            } catch (\Exception $e) {
-                $price = 0;
-            }
         }
-        return array($areaReports, $billReport, $price);
+        return array($areaReports, $billReport);
     }
+
+    public function getSql($owner_id, $counting_month): \Illuminate\Database\Eloquent\Builder
+    {
+        // TODO: Implement getSql() method.
+    }
+
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        return OwnerBillReport::query()
+            ->where('owner_id', $owner_id)
+            ->where('counting_month', $counting_month)
+            ->first();
+    }
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        // TODO: Implement buildExport() method.
+    }
+
+    public function add(array $model)
+    {
+        // TODO: Implement add() method.
+    }
+
+    public function recordReport($counting_month = null)
+    {
+        // TODO: Implement recordReport() method.
+    }
+
+    public function confirmBill($counting_month, $owner_id)
+    {
+        list($areaReports, $billReport) = $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' => [
+                'areaReports' => $areaReports,
+                'billReport' => $billReport,
+            ],
+        ]);
+        $this->confirmBillFeeTotal($counting_month, $owner_id);
+    }
+
+
 }

+ 54 - 0
app/Services/SettlementIndemnityFeeService.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Services;
+
+use App\Order;
+use App\OrderIssue;
+use App\Traits\ServiceAppAop;
+
+class SettlementIndemnityFeeService implements \App\Interfaces\SettlementBillDetailInterface
+
+{
+    const TYPE = '理赔费';
+    use ServiceAppAop;
+    use  \App\Traits\SettlementBillServiceTrait;
+
+    public function getSql($owner_id, $counting_month): \Illuminate\Database\Eloquent\Builder
+    {
+        list($start, $end) = $this->getStartAndEnd($counting_month);
+        return OrderIssue::query()
+            ->with('order.shop')
+            ->whereIn('order_id', Order::query()
+                ->select('id')
+                ->where('owner_id', $owner_id)
+                ->whereBetween('created_at', [$start, $end]))
+            ->whereBetween('created_at', [$start, $end])
+            ->whereNotNull('baoshi_indemnity_money');
+    }
+
+    public function get(array $kvPairs)
+    {
+        return $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->paginate($kvPairs['paginateParams']['paginate'] ?? 50);
+    }
+
+
+    public function switchType($type)
+    {
+        // TODO: Implement switchType() method.
+    }
+
+    public function buildExport($details): array
+    {
+        // TODO: Implement buildExport() method.
+    }
+
+    public function add(array $model)
+    {
+        // TODO: Implement add() method.
+    }
+
+    public function getTotalFee($owner_id, $counting_month)
+    {
+        // TODO: Implement getTotalFee() method.
+    }
+}

+ 32 - 3
app/Services/StationService.php

@@ -13,6 +13,7 @@ use Exception;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Facades\Cache;
 use App\Traits\ServiceAppAop;
+use Illuminate\Support\Facades\DB;
 
 
 class StationService
@@ -134,10 +135,29 @@ class StationService
      *
      * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
      */
-    public function getCacheShelf()
+    public function getCacheShelf($onlyAvailable = false)
     {
-        return Station::query()->where("station_type_id",5)
-            ->whereNotNull("parent_id")->get();
+        $stations = Station::query()->where("station_type_id",5)
+            ->whereNotNull("parent_id");
+        if ($onlyAvailable)$stations->where("status",0)
+            ->whereNotIn("id",Station::query()->select("id")->whereHas("task",function ($query){
+                $query->whereNotIn("status",["完成","取消"]);
+            }))->lockForUpdate();
+        return $stations->get();
+    }
+
+    /**
+     * @param array $codes
+     *
+     * @return array
+     */
+    public function getStationMapping(array $codes):array
+    {
+        $mapping = [];
+        foreach (Station::query()->whereIn("code",$codes)->get() as $station){
+            $station[$station->code] = $station->id;
+        }
+        return $mapping;
     }
 
     /**
@@ -155,6 +175,15 @@ class StationService
         if ($boxId)$update["material_box_id"]=$boxId;
         return Station::query()->where("code",$location)->update($update);
     }
+    /**
+     * 多库位占用
+     * @param array $location
+     * @return bool
+     */
+    public function locationOccupyMulti(array $location):bool
+    {
+        return !!Station::query()->whereIn("code",$location)->update(["status"=>1]);
+    }
 
     /**
      * 库位释放

+ 90 - 23
app/Services/StationTaskBatchService.php

@@ -6,6 +6,8 @@ namespace App\Services;
 
 use App\Exceptions\ErrorException;
 use App\StationTaskBatch;
+use App\StationTaskCommodity;
+use App\TaskTransaction;
 use Carbon\Carbon;
 use Exception;
 use Illuminate\Support\Collection;
@@ -129,18 +131,19 @@ class StationTaskBatchService
 
     /**
      * @param Collection|null $stationTaskBatches
+     * @param string $locationType
      * @return Collection|\Tightenco\Collect\Support\Collection|null 返回执行失败的记录
      * @throws ErrorException
      */
-    function runMany(?Collection $stationTaskBatches):?Collection
+    function runMany(?Collection $stationTaskBatches, $locationType = 'OUTBIN-U-SHAPE-LINE'):?Collection
     {
         LogService::log(__METHOD__,'runMany','波次任务分配6.1:'.json_encode($stationTaskBatches));
         $stationTaskBatches_failed = null;
-        ($execute = function(Collection $stationTaskBatches, &$stationTaskBatches_failed){
+        ($execute = function(Collection $stationTaskBatches, &$stationTaskBatches_failed)use($locationType){
                 if ($stationTaskBatches->isEmpty()) return; //波次任务不存在 跳出
                 $stationTaskBatches_failed = collect();
-                foreach ($stationTaskBatches as $stationTaskBatch) {
-                    $failed = !$this->run($stationTaskBatch); //运行波次 获取执行结果
+                foreach ($stationTaskBatches as $stationTaskBatch){
+                    $failed = !$this->run($stationTaskBatch, $locationType); //运行波次 获取执行结果
                     if ($failed) $stationTaskBatches_failed->push($stationTaskBatch);//执行失败  记录失败波次
                 }
         })($stationTaskBatches, $stationTaskBatches_failed);
@@ -159,13 +162,21 @@ class StationTaskBatchService
         return  $stationTaskBatches_failed;
     }
 
-    function run(StationTaskBatch $stationTaskBatch): bool
+    /**
+     * 解析波次任务 任务下发海柔
+     *
+     * @param StationTaskBatch $stationTaskBatch
+     * @param string $locationType
+     * @return bool
+     * @throws ErrorException
+     */
+    function run(StationTaskBatch $stationTaskBatch, $locationType): bool
     {
         $this->instant($this->foreignHaiRoboticsService,'ForeignHaiRoboticsService');
         $this->instant($this->stationService,'StationService');
         $stationTaskBatch->loadMissing(['station','stationTask.stationTaskMaterialBoxes']);
         LogService::log(__METHOD__,'runMany','波次任务分配6.r2:'.json_encode($stationTaskBatch));
-        $toLocation         = $this->stationService->getULineEntrance($stationTaskBatch['station'])['code'];//获取放线入口
+
         $groupPrefix        = $stationTaskBatch['id'];//将波次任务ID当作组前缀
         $taskMaterialBoxes  = $stationTaskBatch['stationTask']['stationTaskMaterialBoxes'] ??
             (function () use ($stationTaskBatch) {
@@ -173,8 +184,28 @@ class StationTaskBatchService
                 throw new Exception('找不到料箱:' . json_encode($stationTaskBatch));
             })();//存在任务返回任务 否则抛出无料箱异常
         try{
-            $isFetchedFromRobotics = $this->foreignHaiRoboticsService->
+            //获取放线入口
+            switch ($locationType){
+                case 'OUTBIN-U-SHAPE-LINE'://U型线
+                    $toLocation         = $this->stationService->getULineEntrance($stationTaskBatch['station'])['code'];
+                    $isFetchedFromRobotics = $this->foreignHaiRoboticsService->
                     fetchGroup($toLocation, $taskMaterialBoxes, $groupPrefix);//执行料箱任务
+                    break;
+                case 'OUTBIN-CACHE-SHELF'://缓存架
+                    list($toLocation, $taskMaterialBoxes, $map) = $this->apportionLocation($taskMaterialBoxes);
+                    if ($toLocation->count()>0){
+                        $isFetchedFromRobotics = $this->foreignHaiRoboticsService->
+                        fetchGroup_multiLocation($toLocation, $taskMaterialBoxes, $groupPrefix, '立架出至缓存架',20);
+                        foreach ($toLocation as $value){
+                            app("CacheShelfService")->lightUp($value,'3','2');
+                            Cache::forever("CACHE_SHELF_OCCUPANCY_{$map[$value]}",true);
+                        }
+                        app("StationService")->locationOccupyMulti($toLocation->toArray());
+                    }else $isFetchedFromRobotics = true;
+                    break;
+                default:
+                    $isFetchedFromRobotics = false;
+            }
             LogService::log(__METHOD__,'runMany','波次任务分配6.r6:'.json_encode($stationTaskBatch));
         }catch(Exception $e){
             throw new ErrorException('$stationTaskBatch运行波次机器人任务失败,获取组失败: '.$stationTaskBatch->toJson() . $e->getMessage());
@@ -194,7 +225,7 @@ class StationTaskBatchService
         }
         $taskIds = data_get($stationTaskBatch_orCollection, '*.id');
         $this->markProcessing_byIds($taskIds);
-        app("StorageService")->handleStorage($stationTaskBatch_orCollection);
+        //app("StorageService")->handleStorage($stationTaskBatch_orCollection);
     }
     function markProcessing_byIds($ids)
     {
@@ -233,24 +264,60 @@ class StationTaskBatchService
             ->update(['status'=>'完成']);
     }
 
-//    function markFinished($stationTaskBatches)
-//    {
-//        if (get_class($stationTaskBatches)==StationTaskBatch::class){
-//            $stationTaskBatches = collect($stationTaskBatches);
-//        }
-//        StationTaskBatch::query()
-//            ->whereIn('id', data_get($stationTaskBatches, '*.id'))
-//            ->update(['status'=>'完成']);
-//
-//        $this->stationTaskService
-//            ->markProcessing_byId(
-//                data_get($stationTaskBatches, '*.station_id')
-//            );
-//    }
-
     function markExcepted(StationTaskBatch $stationTaskBatch)
     {
         $stationTaskBatch['status'] = '异常';
         $stationTaskBatch           ->update();
     }
+
+    /**
+     * 为任务分配缓存架库位
+     *
+     * @param \Illuminate\Database\Eloquent\Collection $taskMaterialBoxes
+     *
+     * @return array
+     */
+    public function apportionLocation(Collection $taskMaterialBoxes):array
+    {
+        $taskMaterialBoxes->loadMissing(["stationTaskCommodities.order","stationTaskCommodities.commodity.barcodes"]);
+        //获取可用的库位 加行锁
+        $stations = app("StationService")->getCacheShelf(true);
+        $location = [];
+        $map = [];
+        foreach ($stations as $station){
+            $location[] = $station->code;
+            $map[$station->code] = $station->id;
+        }
+        /** @var Collection $handleTask */
+        $handleTask = $taskMaterialBoxes->splice(0,count($location));
+        $toLocation = collect();
+        $updateTask = [["id","station_id"]];
+        $insertTransaction = [];
+        $exeInsert = function ($task,$taskCommodity,$status)use(&$insertTransaction){
+            $insertTransaction[] = [
+                "doc_code" => $taskCommodity->order->code ?? "",
+                "bar_code" => $taskCommodity->commodity->barcodes[0]->code ?? "",
+                "to_station_id" => $task->station_id,
+                "material_box_id" => $task->material_box_id,
+                "task_id" => $task->id,
+                "commodity_id" => $taskCommodity->commodity_id,
+                "amount" => $taskCommodity->amount,
+                "type" => "出库",
+                "status" => $status,
+                "mark" => 2,
+                "bin_number"=>$taskCommodity->bin_number,
+            ];
+        };
+        foreach ($handleTask as $index=>$task){
+            $task->station_id = $map[$location[$index]];
+            $toLocation->push($location[$index]);
+            $handleTask->offsetSet($index,$task);
+            $updateTask[] = ["id"=>$task->id,"station_id"=>$task->station_id];
+            foreach ($task->stationTaskCommodities as $taskCommodity)$exeInsert($task,$taskCommodity,0);
+        }
+        if ($handleTask->count()>0)app("BatchUpdateService")->batchUpdate("station_task_material_boxes",$updateTask);
+        foreach ($taskMaterialBoxes as $obj)foreach ($obj->stationTaskCommodities as $taskCommodity)$exeInsert($obj,$taskCommodity,3);
+        TaskTransaction::query()->insert($insertTransaction);
+        return array($toLocation, $handleTask, $map);
+    }
 }

+ 28 - 33
app/Services/StationTaskMaterialBoxService.php

@@ -8,6 +8,7 @@ use App\Batch;
 use App\Events\BroadcastToStation;
 use App\Exceptions\ErrorException;
 use App\Exceptions\Exception;
+use App\Jobs\CacheShelfTaskJob;
 use App\MaterialBox;
 use App\OrderCommodity;
 use App\StationCacheShelfGrid;
@@ -175,14 +176,14 @@ class StationTaskMaterialBoxService
                 case '入立库':
                     $stationTaskMaterialBox->materialBox['status']='在立库';
                     $stationTaskMaterialBox->materialBox->update();
-                    $stationTaskMaterialBox->loadMissing("station");    //提前加载站,后续都需要站信息来处理
-                    $this->storageService->releaseOccupation($stationTaskMaterialBox); //释放库位占用
-                    $this->storageService->checkMark($stationTaskMaterialBox); //检查标记并做一些特殊处理
+                    //$this->storageService->checkMark($stationTaskMaterialBox); //检查标记并做一些特殊处理
                     break;
                 case '入缓存架':
                     $stationTaskMaterialBox->materialBox['status']='在缓存架';
                     $stationTaskMaterialBox->materialBox->update();
+                    $stationTaskMaterialBox->loadMissing("station");    //提前加载站,后续都需要站信息来处理
                     $this->storageService->putCacheShelf($stationTaskMaterialBox);
+                    $this->storageService->releaseOccupation($stationTaskMaterialBox); //释放库位占用
                     break;
                 default:;
             }
@@ -206,20 +207,24 @@ class StationTaskMaterialBoxService
             ->update(["status"=>"完成"]);
     }
 
-    // TODO 料箱处理
+    /**
+     * 取出料箱通知
+     *
+     * @param $stationTaskMaterialBox
+     * @throws \Exception
+     */
     function markHasTaken($stationTaskMaterialBox)
     {
-        //TODO: 标记 料箱位置(需要其字段存在)$stationTaskMaterialBox['materialBox']['position']
         $this->instant($this->cacheShelfService,'CacheShelfService');
-
-        // 料箱从缓存架上拿走
-        if($stationTaskMaterialBox['station']['stationType']['name']=='缓存架'
-            &&$stationTaskMaterialBox['type']=='取'){
-
-            $stationTaskMaterialBox['status'] = '完成';
-            $result = $this->cacheShelfService->lightOffTask($stationTaskMaterialBox['station']['code'],0);
-            if($result['success'])
-                $this->markProcessed($stationTaskMaterialBox);
+        //维护缓存架可用度
+        $map = Cache::get("CACHE_SHELF_MAPPING",function (){return [];});
+        if (isset($map[$stationTaskMaterialBox->material_box_id])){
+            $available=Cache::get("CACHE_SHELF_AVAILABLE",function (){return [];});
+            $available[$map[$stationTaskMaterialBox->material_box_id]] = true;
+            Cache::forever("CACHE_SHELF_AVAILABLE",$available);
+            CacheShelfTaskJob::dispatch("CACHE_SHELF_AVAILABLE",count($available))->delay(now()->addSeconds(config("haiRou.cacheShelf.outBinAwait")));
+            unset($map[$stationTaskMaterialBox->material_box_id]);
+            Cache::forever("CACHE_SHELF_MAPPING",$map);
         }
     }
 
@@ -331,25 +336,15 @@ class StationTaskMaterialBoxService
     function getServingTaskType(StationTaskMaterialBox $stationTaskMaterialBox): string
     {
         $stationTaskMaterialBox->load('station.stationType');
-        if($isBatching=(
-            $stationTaskMaterialBox['station_task_batch_id'] &&
-            $stationTaskMaterialBox['station']['stationType']['name'] == '料箱监视器')
-        ){
-            return '分波次';
-        }
-        if($isPuttingBack=(
-            $stationTaskMaterialBox['station']['stationType']['name'] == '立库')
-        ){
-            return '入立库';
-        }
-        if($isCacheShelf=(
-            $stationTaskMaterialBox['station']['stationType']['name'] == '缓存架')
-        ){
-            return '入缓存架';
+        switch ($stationTaskMaterialBox['station']['stationType']['name']){
+            case "立库":
+                return '入立库';
+            case "缓存架":
+                return '入缓存架';
+            case "料箱监视器":
+                if ($stationTaskMaterialBox['station_task_batch_id'])return "分波次";
+            default:
+                throw new ErrorException('当前类型找不到');
         }
-//        if($isStoring=false){
-//            return '入库';
-//        }
-        throw new ErrorException('当前类型找不到');
     }
 }

+ 136 - 50
app/Services/StorageService.php

@@ -5,6 +5,7 @@ namespace App\Services;
 use App\CommodityMaterialBoxModel;
 use App\Components\ErrorPush;
 use App\MaterialBoxCommodity;
+use App\Order;
 use App\Station;
 use App\StationTask;
 use App\StationTaskMaterialBox;
@@ -16,6 +17,7 @@ use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Str;
 
@@ -33,24 +35,69 @@ class StorageService
     {
         DB::beginTransaction();
         try{
-            Station::query()->where("id",$stationTaskMaterialBox->station_id)
-                ->update(["material_box_id"=>$stationTaskMaterialBox->material_box_id,"status"=>0]);
             $stationTaskMaterialBox->loadMissing("station");
             //如果为半箱位置 清理原有任务
             if ($stationTaskMaterialBox->station && app("StationService")->isHalfBoxLocation($stationTaskMaterialBox->station)){
-                $task = TaskTransaction::query()->selectRaw("1")->with("materialBox")->where("fm_station_id",$stationTaskMaterialBox->station_id)
-                    ->where("status",0)->first();
-                if ($task)app("CacheShelfService")->lightUp($stationTaskMaterialBox->station->code,'1','0',[
-                    "title"=>$task->materialBox->code ?? '',
-                    "detail01"=>"{$task->doc_code}",
-                    "detail02"=>"商品条码:{$task->bar_code}",
-                    "detail03"=>"上架数量:{$task->amount}",
-                ]);
-                else $this->clearTask([$stationTaskMaterialBox->station->code]);
+                app("StationService")->locationFreed($stationTaskMaterialBox->station->code,$stationTaskMaterialBox->material_box_id);
+                //清除海柔库位信息
+                $this->clearTask([$stationTaskMaterialBox->station->code]);
+                $stationId = $stationTaskMaterialBox->station_id;
+                $tasks = TaskTransaction::query()->with("materialBox")->where(function ($query)use($stationId){
+                    $query->where("fm_station_id",$stationId)->orWhere("to_station_id",$stationId);
+                })->where("status",0)->get();
+                if ($tasks->count()!=0){
+                    $options = [];
+                    switch ($tasks[0]->mark){
+                        case 1:
+                            $options["title"] = '上架任务';
+                            break;
+                        case 2:
+                            $options["title"] = '出库任务';
+                            break;
+                        default:
+                            $options["title"] = '未知类型';
+                    }
+                    switch ($tasks->count()){
+                        case 1:
+                            $task = $tasks[0];
+                            $options["detail01"] = $task->materialBox->code ?? '';
+                            $options["detail02"] = $task->doc_code;
+                            $options["detail03"] = $task->bar_code;
+                            $options["qty01"] = $task->amount;
+                            $options["uomDesc01"] = '件';
+                            $options["qty02"] = $task->bin_number;
+                            $options["uomDesc02"] = '号';
+                            break;
+                        default:
+                            $count = count(array_unique(array_column($tasks->toArray(),"commodity_id")));
+                            if ($count==1){
+                                $options["detail01"] = $tasks[0]->bar_code;
+                                $options["detail02"] = "";
+                                $options["detail03"] = "";
+                                foreach ($tasks as $task){
+                                    if (mb_strlen($options["detail02"])>20){
+                                        $options["detail03"] .= $task->bin_number."号-".$task->amount."件,";
+                                    }else $options["detail02"] .= $task->bin_number."号-".$task->amount."件,";
+                                }
+                                $options["detail02"] = rtrim($options["detail02"],",");
+                                $options["detail03"] = rtrim($options["detail03"],",");
+                            }else{
+                                $task = $tasks[0];
+                                $options["detail01"] = $task->materialBox->code ?? '';
+                                $options["detail02"] = "货品过多请自行核对";
+                                $options["detail03"] = "波次:".$task->doc_code ?
+                                    (Order::query()->with("batch")->where("code",$task->doc_code)->first()->batch->code ?? '无') : '无';
+                            }
+                            break;
+                    }
+                    app("CacheShelfService")->lightUp($stationTaskMaterialBox->station->code,'2','0',$options);
+                    Cache::forget("CACHE_SHELF_OCCUPANCY_{$stationTaskMaterialBox->station->id}");//关闭无限亮灯
+                }
             }
             DB::commit();
         }catch (\Exception $e){
             DB::rollBack();
+            $this->push(__METHOD__."->".__LINE__,"清除任务亮灯失败","错误信息:".$e->getMessage()."  执行任务信息:".json_encode($stationTaskMaterialBox));
         }
     }
 
@@ -61,7 +108,7 @@ class StorageService
      */
     public function releaseOccupation($stationTaskMaterialBox)
     {
-        if (!app("StationService")->isCacheShelfLocation($stationTaskMaterialBox->station))return;
+        if (!app("StationService")->isHalfBoxLocation($stationTaskMaterialBox->station))return;
         app("StationService")->locationFreed($stationTaskMaterialBox->station->code);
     }
 
@@ -75,8 +122,8 @@ class StorageService
         $task = TaskTransaction::query()->where("material_box_id",$stationTaskMaterialBox->material_box_id)
             ->where("status",0)->first();
         if (!$task)return;
-        //灯闪烁
-        if ($task->type == '入库' && $task->mark == 1)app("CacheShelfService")->lightUp($stationTaskMaterialBox->station->code,'2','2',["title"=>'机器人取箱中,禁止操作',]);
+        //灯闪烁
+        if ($task->type == '入库' && $task->mark == 1)app("CacheShelfService")->lightUp($stationTaskMaterialBox->station->code,'3','2',["title"=>'机器人取箱中,禁止操作',]);
     }
 
     /**
@@ -88,47 +135,88 @@ class StorageService
      *
      * @throws
      */
-    public function checkStorage(Station $station)
+    public function checkStorage(Station $station):?bool
     {
-        $task = TaskTransaction::query()->with("materialBox")->where("fm_station_id",$station->id)
-            ->where("status",0)->first();
-        if (!$task)return true;
-        //建立入库任务,通知入库,完善库存
-        if ($task->type == '入库' && $task->mark == 1){
-            DB::beginTransaction();
+        $stationId = $station->id;
+        $task = TaskTransaction::query()->with("materialBox")->where(function ($query)use($stationId){
+            $query->where("fm_station_id",$stationId)->orWhere("to_station_id",$stationId);
+        })->where("status",0)->first();
+        if (!$task)return null;
+        switch ($task->type){
+            case "入库":
+                switch ($task->mark){
+                    case 1:
+                        return $this->handlePaTransaction($task, $station);
+                }
+                break;
+            case "出库":
+                switch ($task->mark){
+                    case 2:
+                        return $this->handleOutTransaction($station);
+                }
+        }
+        return null;
+    }
+
+    /**
+     * 处理出货交易
+     *
+     * @param Station|\stdClass $station
+     *
+     * @return bool
+     */
+    private function handleOutTransaction($station):bool
+    {
+        return TaskTransaction::query()->with("materialBox")->orWhere("to_station_id",$station->id)
+            ->where("status",0)->update([
+                "status" => 1,
+            ]) > 0;
+    }
+
+    /**
+     * 处理上架交易
+     *
+     * @param TaskTransaction|\stdClass $task
+     * @param Station|\stdClass $station
+     *
+     * @return bool
+     * @throws
+     */
+    private function handlePaTransaction($task, $station):bool
+    {
+        DB::beginTransaction();
+        try{
+            //get flux
+            $tasks = $this->getFluxTask($task->doc_code,$task->bar_code,$task->amount);
+            if (!$tasks)return false;
+            $ide = $task->materialBox->code;
+            DB::connection("oracle")->beginTransaction();
             try{
-                //get flux
-                $tasks = $this->getFluxTask($task->doc_code,$task->bar_code,$task->amount);
-                if (!$tasks)return false;
-                $ide = $task->materialBox->code;
-                DB::connection("oracle")->beginTransaction();
-                try{
-                    foreach ($tasks as $t)if (!$this->fluxPA($t,$ide)){
-                        DB::connection("oracle")->rollBack();
-                        return false;
-                    };
-                }catch(\Exception $e){
+                foreach ($tasks as $t)if (!$this->fluxPA($t,$ide)){
                     DB::connection("oracle")->rollBack();
                     return false;
-                }
-                $taskMaterialBox = $this->createWarehousingTask($station->id,$task->material_box_id);//建立入库任务
-                //2021-07-27 取消WAS库存维护
-                //if (!$this->enterWarehouse($task->material_box_id,$task->commodity_id,$task->amount))throw new \Exception("库存异常"); //处理库存
-                $task->update([
-                    "task_id" => $taskMaterialBox->id,
-                    "status" => 1,
-                ]);//标记事务完成
-                app("ForeignHaiRoboticsService")->putBinToStore_fromCacheShelf($taskMaterialBox,$station); //呼叫机器人入库
-                DB::commit();
-                DB::connection("oracle")->commit();
-                return true;
+                };
             }catch(\Exception $e){
-                DB::rollBack();
                 DB::connection("oracle")->rollBack();
                 return false;
             }
+            //$taskMaterialBox = $this->createWarehousingTask($station->id,$task->material_box_id);//建立入库任务
+            //2021-07-27 取消WAS库存维护
+            //if (!$this->enterWarehouse($task->material_box_id,$task->commodity_id,$task->amount))throw new \Exception("库存异常"); //处理库存
+            $task->update([
+                //"task_id" => $taskMaterialBox->id,
+                "status" => 1,
+            ]);//标记事务完成
+            //返回亮灯 此处不入库 再下一次按时入库
+            //app("ForeignHaiRoboticsService")->putBinToStore_fromCacheShelf($taskMaterialBox,$station); //呼叫机器人入库
+            DB::commit();
+            DB::connection("oracle")->commit();
+            return true;
+        }catch(\Exception $e){
+            DB::rollBack();
+            DB::connection("oracle")->rollBack();
+            return false;
         }
-        return true;
     }
 
     /**
@@ -420,8 +508,7 @@ sql;
         }
     }
 
-    private function
-    checkAsn($task)
+    private function checkAsn($task)
     {
         $sql = <<<SQL
 SELECT 1 FROM DOC_ASN_DETAILS WHERE ASNNO = ? AND LINESTATUS != '40'
@@ -432,8 +519,7 @@ SQL;
         $sql = <<<SQL
 SELECT 1 FROM TSK_TASKLISTS WHERE TASKPROCESS != '99' AND TASKTYPE = 'PA' AND DOCNO = ?
 SQL;
-        $task = DB::connection("oracle")->selectOne(DB::raw($sql),[$task->docno]);
-        if ($task)return;
+        if (DB::connection("oracle")->selectOne(DB::raw($sql),[$task->docno]))return;
 
         DB::connection("oracle")->update(DB::raw("UPDATE DOC_ASN_HEADER SET asnstatus = '99',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ?"),
             [date("Y-m-d H:i:s"),$task->who,$task->docno]);

+ 12 - 3
app/Station.php

@@ -19,7 +19,16 @@ class Station extends Model
         0 => "正常",
         1 => "占用",
     ];
+    /*站相关 CACHE说明
+     * CACHE_SHELF_OCCUPANCY_{ID}   //bool:缓存架占用标记,开启此标记后连续排灯无效
+     * CACHE_SHELF_MAPPING          //array(map):缓存架映射标记,用来映射入库任务的真实库位 CacheShelfTaskJob:materialBoxMappingCacheShelf详细描述此流程
+     * CACHE_SHELF_AVAILABLE        //array(map):缓存架可用标记,映射缓存架是否可以被下达出库任务
+     * */
 
+    public function task()
+    {
+        return $this->hasOne(StationTaskMaterialBox::class,"station_id","id");
+    }
     public function materialBox():BelongsTo
     {
         return $this->belongsTo(MaterialBox::class);
@@ -41,14 +50,14 @@ class Station extends Model
         return $this->hasMany(StationTask::class)
             ->where('created_at','>=',now()->format('Y-m-d'))
             ->orderBy('status')
-            ->orderByDesc('id')
-            ;
+            ->orderByDesc('id');
     }
     public function stationTasks()
     {   //站任务
         return $this->hasMany(StationTask::class,"id","station_type_id");
     }
-    public function stationTypeBinMonitor(){
+    public function stationTypeBinMonitor()
+    {
         return $this->hasOne(StationTypeBinMonitor::class);
     }
 

+ 4 - 0
app/StationTaskCommodity.php

@@ -25,4 +25,8 @@ class StationTaskCommodity extends Model
     {
         return $this->belongsTo(StationTask::class);
     }
+    public function order()
+    {
+        return $this->belongsTo(Order::class);
+    }
 }

+ 11 - 3
app/TaskTransaction.php

@@ -22,21 +22,29 @@ class TaskTransaction extends Model
         "type",
         "status",
         "user_id",
-        "mark"
+        "mark",
+        "bin_number",
     ];
 
     const STATUS = [
         0 => "待做",
         1 => "完成",
-        2 => "失败"
+        2 => "失败",
+        3 => "队列",
     ];
     const MARK = [
         0 => "无",
-        1 => "缓存架半箱入库"
+        1 => "缓存架半箱入库",
+        2 => "料箱出至缓存架"
     ];
 
     public function materialBox()
     {   //料箱
         return $this->belongsTo(MaterialBox::class);
     }
+
+    public function task()
+    {   //任务
+        return $this->belongsTo(StationTaskMaterialBox::class,"task_id");
+    }
 }

+ 70 - 0
app/Traits/SettlementBillServiceTrait.php

@@ -0,0 +1,70 @@
+<?php
+
+
+namespace App\Traits;
+
+
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use App\Services\OwnerBillReportArchiveService;
+use App\Services\OwnerFeeTotalService;
+use Carbon\Carbon;
+
+trait SettlementBillServiceTrait
+{
+    /**
+     * @param $counting_month
+     * @return array
+     */
+    public function getStartAndEnd($counting_month): array
+    {
+        $start = Carbon::parse($counting_month)->startOfMonth()->startOfDay()->toDateTimeString();
+        $end = Carbon::parse($counting_month)->endOfMonth()->endOfDay()->toDateTimeString();
+        return array($start, $end);
+    }
+
+    /**
+     * 确认账单
+     * @param $counting_month
+     * @param $owner_id
+     */
+    public function confirmBill($counting_month, $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::TYPE,
+            'archiver_id' => auth()->id(),
+            'archived_at' => now(),
+            'information' => [],
+        ]);
+        $this->confirmBillFeeTotal($counting_month, $owner_id);
+    }
+
+    /**
+     * 确认总账单费用
+     * @param $counting_month
+     * @param $owner_id
+     */
+    public function confirmBillFeeTotal($counting_month, $owner_id): void
+    {
+        if ($this::TYPE !== '总费用') {
+            /**@var $archiveService  OwnerBillReportArchiveService */
+            $archiveService = app('OwnerBillReportArchiveService');
+            if (count($archiveService->getUnAchieved($counting_month, $owner_id)) == 0) {//全部子项已经确认完成
+                //确认总费用
+                /**@var $totalFeeService OwnerFeeTotalService */
+                $totalFeeService = app('OwnerFeeTotalService');
+                $totalFeeService->confirmBill($counting_month, $owner_id);
+            }
+        }
+    }
+}

+ 57 - 0
app/Traits/SettlementBillTrait.php

@@ -0,0 +1,57 @@
+<?php
+
+
+namespace App\Traits;
+
+
+use App\OwnerBillReport;
+use App\OwnerBillReportArchive;
+use Illuminate\Http\Request;
+use Illuminate\Support\Collection;
+
+trait SettlementBillTrait
+{
+    /**
+     * @param $year
+     * @param $month
+     * @param $owner_id
+     * @return array
+     */
+    public function getRequestParams($year, $month, $owner_id): array
+    {
+        $permittingOwnerIds = app('UserService')->getPermittingOwnerIds(auth()->user());
+        if (is_null($year)) {
+            $year = now()->subMonth()->year;
+        }
+        if (is_null($month)) {
+            $month = now()->subMonth()->month;
+        }
+        $counting_month = \Carbon\Carbon::parse($year . '-' . $month . '-' . '01')->toDateString();
+        if (is_null($owner_id)) {
+            $owner_id = $permittingOwnerIds[0];
+        }
+        return array($permittingOwnerIds, $counting_month, $owner_id);
+    }
+
+    /**
+     * @param Request $request
+     * @param $counting_month
+     * @param $owner_id
+     * @return Collection|\Tightenco\Collect\Support\Collection
+     */
+    public function buildRequest(Request $request, $counting_month,$owner_id)
+    {
+        $request = $request->all();
+        $request['year'] = \Carbon\Carbon::parse($counting_month)->year;
+        $request['month'] = \Carbon\Carbon::parse($counting_month)->month;
+        $request['owner_id'] = $owner_id;
+        return collect($request);
+    }
+
+    public function confirmBill(Request $request): \Illuminate\Http\RedirectResponse
+    {
+        list($permittingOwnerIds, $counting_month, $owner_id) = $this->getRequestParams($request->year, $request->month, $request->owner_id);
+        $this->service->confirmBill($counting_month, $owner_id);
+        return back()->with('success', '确认成功');
+    }
+}

+ 5 - 2
app/Waybill.php

@@ -2,12 +2,11 @@
 
 namespace App;
 
-use App\Services\UserService;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
 use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Relations\HasOne;
 use Illuminate\Database\Eloquent\SoftDeletes;
-use Illuminate\Support\Facades\Auth;
 
 use App\Traits\ModelLogChanging;
 use Illuminate\Support\Facades\DB;
@@ -163,5 +162,9 @@ column
         });
     }
 
+    public function ownerWayBillFeeDetail(): HasOne
+    {
+        return $this->hasOne(OwnerWayBillFeeDetail::class);
+    }
 
 }

+ 2 - 0
config/api_logistic.php

@@ -183,6 +183,7 @@ return [
             'passwordSigning' => 'N', //是否口令签收 仅适用于快递,Y:需要 N: 不需要;若为Y,必须收货人提供验证码给快递员才能签收,该服务是有偿的,具体费用请让我司收货营业部联系张宁(491407),请慎重使用!
             'uri' => [
                 'create_order' => 'http://dpsanbox.deppon.com/sandbox-web/dop-standard-ewborder/createOrderNotify.action',
+                'order_locus' => 'http://dpsanbox.deppon.com/sandbox-web/standard-order/newTraceQuery.action',
             ]
         ],
         'prod'=>[
@@ -200,6 +201,7 @@ return [
             'passwordSigning' => 'N', //是否口令签收 仅适用于快递,Y:需要 N: 不需要;若为Y,必须收货人提供验证码给快递员才能签收,该服务是有偿的,具体费用请让我司收货营业部联系张宁(491407),请慎重使用!
             'uri' => [
                 'create_order' => 'http://dpsanbox.deppon.com/sandbox-web/dop-standard-ewborder/createOrderNotify.action',
+                'order_locus' => 'http://dpsanbox.deppon.com/sandbox-web/standard-order/newTraceQuery.action',
             ]
         ]
     ],

+ 2 - 0
config/haiRou.php

@@ -9,5 +9,7 @@ return [
     "cacheShelf" => [
         /* call await time/second */
         "callAwait" => 3,
+        /* outbound waiting time/second */
+        "outBinAwait" => 60,
     ],
 ];

+ 0 - 7
config/sync,php.php

@@ -1,7 +0,0 @@
-<?php
-return [
-    'order_tracking_import' => [
-        'import' => 20,
-        'start_at'=> '',
-    ],
-];

+ 12 - 0
database/factories/OwnerBillTotalFactory.php

@@ -0,0 +1,12 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerBillTotal;
+use Faker\Generator as Faker;
+
+$factory->define(OwnerBillTotal::class, function (Faker $faker) {
+    return [
+        //
+    ];
+});

+ 3 - 0
database/factories/OwnerFeeDetailFactory.php

@@ -23,6 +23,9 @@ $factory->define(OwnerFeeDetail::class, function (Faker $faker) {
         "weight" => mt_rand(10, 2600) / 88,           //重量
         "work_fee" => mt_rand(100, 10000) / 10,         //作业费
         "logistic_fee" => mt_rand(100, 10000) / 10,     //物流费
+        "logistic_tax_fee" => mt_rand(100, 10000) / 10,     //物流税费
         "province" => $faker->randomElement($province),     //物流费
+        "logistic_id" => rand(1,100),     //物流费
+        'created_at' => now()->subMonth()->startOfMonth()->addDays(random_int(1, 28)),
     ];
 });

+ 12 - 0
database/factories/OwnerFeeTotalFactory.php

@@ -0,0 +1,12 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerFeeTotal;
+use Faker\Generator as Faker;
+
+$factory->define(OwnerFeeTotal::class, function (Faker $faker) {
+    return [
+        //
+    ];
+});

+ 3 - 1
database/factories/OwnerLogisticFeeDetailFactory.php

@@ -17,8 +17,10 @@ $factory->define(OwnerLogisticFeeDetail::class, function (Faker $faker) {
         'additional_price' => random_int(1, 100),
         'logistic_id' => $faker->randomElement($logistic_ids),
         'province' => $faker->randomElement($province),
-        'owner_id' => 8,
+        'owner_id' => random_int(1, 100),
         'additional_weigh_weight' => random_int(1, 100),
+        'tax_fee' => random_int(1, 100),
+        'fee' => random_int(1, 100),
         'created_at' => now()->subMonth()->startOfMonth()->addDays(random_int(1, 28))->toDateTimeString(),
         'updated_at' => now()->subMonth()->startOfMonth()->addDays(random_int(1, 28))->toDateTimeString(),
     ];

+ 3 - 2
database/factories/OwnerLogisticFeeReportFactory.php

@@ -12,7 +12,7 @@ $factory->define(OwnerLogisticFeeReport::class, function (Faker $faker) {
         'owner_logistic_sum_fee_report_id' => random_int(1, 100),
         'logistic_id' => $faker->randomElement($logistic_ids),
         'province' => $faker->randomElement($province),
-        'counted_date' => now()->subMonths(random_int(1,12))->startOfMonth()->toDateString(),
+        'counted_date' => now()->subMonths(random_int(1, 12))->startOfMonth()->toDateString(),
         'initial_weight' => random_int(1, 100),
         'initial_weight_price' => random_int(1, 100),
         'initial_amount' => random_int(1, 100),
@@ -20,6 +20,7 @@ $factory->define(OwnerLogisticFeeReport::class, function (Faker $faker) {
         'additional_price' => random_int(1, 100),
         'additional_amount' => random_int(1, 100),
         'fee' => random_int(1, 100),
-        'owner_id' => 8,
+        'tax_fee' => random_int(1, 100),
+        'owner_id' => random_int(1, 100),
     ];
 });

+ 21 - 0
database/factories/OwnerPriceOperationItemFactory.php

@@ -0,0 +1,21 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerPriceOperationItem;
+use Faker\Generator as Faker;
+
+$factory->define(OwnerPriceOperationItem::class, function (Faker $faker) {
+    $strategy = ['起步', '默认', '特征'];
+    return [
+        "owner_price_operation_id"=>random_int(1,100),         //作业计费ID
+        "strategy"=>$faker->randomElement($strategy),                         //子策略
+        "amount"=>random_int(1,100),                           //起步数
+        "unit_id"=>random_int(1,7),                          //单位ID
+        "unit_price"=>random_int(1,100),                       //单价
+        "feature"=>random_int(1,100),                          //特征
+        "priority"=>random_int(1,100),                         //优先级 值越大越高
+        "discount_price"=>random_int(1,100),                   //减免单价
+        "odd_price"=>random_int(1,100),                        //零头价
+    ];
+});

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