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

手工呼叫与缓存架入库BUG修复

Zhouzhendong 4 лет назад
Родитель
Сommit
aa325c80ed

+ 61 - 105
app/Http/Controllers/StorageController.php

@@ -192,11 +192,12 @@ sql;
     public function acquireBox()
     {
         $this->gate("入库管理-入库-半箱补货入库");
-        $param = request()->only(["track","barCode","lotNum","amount"]);
+        $param = request()->only(["track","barCode","lotNum","amount","call"]);
         $track = $param["track"] ?? null;
         $barCode = $param["barCode"] ?? null;
         $lotNum = $param["lotNum"] ?? null;
         $amount = $param["amount"] ?? null;
+        $manualCall = $param["call"] ?? false;
         if (!$track || !$barCode || !$lotNum || !$amount)$this->error("提交信息不完整");
 
         $sql = <<<SQL
@@ -267,14 +268,39 @@ SQL;
             $location = collect();
             $ids = [];
             //寻找半箱
-            foreach ($models as $model){
-                list($invs,$map) = app("StorageService")->getMaxAvailableHalfBoxLocation($model->commodity, request("lotNum"));
-                if (!$invs)continue;
+            $sql = <<<SQL
+SELECT LOCATIONID,QTY FROM INV_LOT_LOC_ID WHERE LOTNUM = '{$lotNum}'
+AND LOCATIONID LIKE 'IDE%' AND SKU = '{$commodity->sku}' AND TRACEID = '*' AND QTY > 0 AND QTY > 0 ORDER BY QTY
+SQL;
+            $invs = DB::connection("oracle")->select(DB::raw($sql));
+            if ($invs){
+                $map = [];
+                $codes = [];
                 foreach ($invs as $inv){
+                    $map[$inv->locationid] = $inv->qty;
+                    $codes[] = $inv->locationid;
+                }
+                $modelMap = [];
+                $orderBy = "CASE material_box_model_id ";
+                foreach ($models as $key=>$model){
+                    $orderBy .= 'WHEN '.$model->id." THEN ".$key;
+                    $modelMap[$model->id] = $model->commodity->maximum;
+                }
+                $orderBy.= " END";
+                $boxes = MaterialBox::query()->whereIn("code",$codes)->orderByRaw($orderBy)->lockForUpdate()->get();
+                //筛选下海柔可用箱
+                list($codes,$notCodes) = app("MaterialBoxService")->checkHaiQ(array_column($boxes->toArray(),"code"));
+                if (!$codes)$boxes = new \Illuminate\Database\Eloquent\Collection();
+                $boxes = $boxes->filter(function ($box)use($codes,$notCodes){
+                    if (!isset($codes[$box->code]) || isset($notCodes[$box->code]))return false;
+                    return true;
+                });
+                foreach ($boxes as $box){
+                    if ($modelMap[$box->material_box_model_id]<=$map[$box->code])continue;
+                    $num = $modelMap[$box->material_box_model_id]-$map[$box->code];
                     $station = $stations->last();
-                    $boxId = $map[$inv->locationid];
-                    $number = $amount >= $inv->qty ? $amount-$inv->qty : $amount;
-                    $task = $exe($station, $boxId, $number);
+                    $number = $amount >= $num ? $amount-$num : $amount;
+                    $task = $exe($station, $box->id, $number);
                     if ($station){
                         $stations->offsetUnset($stations->count()-1);
                         $collection->push($task);
@@ -284,8 +310,8 @@ SQL;
                     $amount -= $number;
                     if ($amount==0)break;
                 }
-                if ($amount==0)break;
             }
+
             if ($amount){
                 //寻找空箱
                 $blacklist = [];//空箱逐一寻找需要列队黑名单
@@ -311,7 +337,8 @@ SQL;
             if ($location->count()){
                 /** @var ForeignHaiRoboticsService $service */
                 $service = app("ForeignHaiRoboticsService");
-                $result = $service->fetchGroup_multiLocation($location,$collection,'','立架出至缓存架');
+                if ($manualCall)$result = $this->mergeIntoCache($location,$collection);
+                else $result = $service->fetchGroup_multiLocation($location,$collection,'','立架出至缓存架');
                 if (!$result){
                     DB::rollBack();
                     $this->error("机器人呼叫失败,海柔任务错误");
@@ -338,105 +365,34 @@ SQL;
     }
 
     /**
-     * 取得料箱 废弃
+     * 并入缓存 等待呼叫
+     *
+     * @param Collection $location
+     * @param Collection $collection
+     *
+     * @return bool
      */
-    public function acquireBoxTemp()
+    public function mergeIntoCache(Collection $location,Collection $collection):bool
     {
-        $this->gate("入库管理-入库-半箱补货入库");
-        $boxId = request("material_box_id");
-        $modelId = request("material_box_model_id");
-        if (!$modelId)$this->error("商品未设定库存上限");
-        //获取目标库位
-        $station = app("StationService")->getMirrorMappingLocation(request("station"));
-        if (!$station)$this->error("未知库位");
-        $isAvailable = app("StationService")->isAvailable($station);
-        if (!$isAvailable)$this->error("库存被占用或存在任务未处理");
-        $amount = app("StorageService")->checkPutAmount(request("track"),request("barCode"),request("lotNum"));
-        if ($amount<request("amount"))$this->error("待上架数量不足,最大可上数量为{$amount}");
-
-        //发起取箱任务
-        $exe = function ($boxId)use($station,$amount){
-            DB::beginTransaction();
-            try{
-                $collection = new Collection();
-                $task = StationTask::query()->create([
-                    'status' => "待处理",
-                    'station_id' => $station->id,
-                ]);
-                $collection->add(StationTaskMaterialBox::query()->create([
-                    'station_id' => $station->id,
-                    'material_box_id'=>$boxId,
-                    'status'=>"待处理",
-                    'type' => '取',
-                    'station_task_id' => $task->id,
-                ]));
-                if (!app("ForeignHaiRoboticsService")->fetchGroup($station->code,$collection,'','立架出至缓存架'))$this->error("呼叫机器人失败");
-                //生成临时任务事务
-                TaskTransaction::query()->create([
-                    //"doc_code" => request("asn"),
-                    "bar_code" => request("barCode"),
-                    "fm_station_id" => $station->id,
-                    "material_box_id" => $boxId,
-                    "commodity_id" => request("commodity_id"),
-                    "amount" => request("amount"),
-                    "type" => "入库",
-                    "user_id" => Auth::id(),
-                    "mark" => 1,
-                    "lot_num" => request("lotNum"),
-                    "track_num" => request("track"),
-                ]);
-                //亮灯
-                app("CacheShelfService")->lightUp($station->code,'3','0');
-                app("StationService")->locationOccupy($station->code);//占用库位
-                Cache::forever("CACHE_SHELF_OCCUPANCY_{$station->id}",true);
-                DB::commit();
-                return true;
-            }catch (\Exception $e){
-                DB::rollBack();
-                return false;
-            }
-        };
-        //检查获取的料箱仍然可用
-        if ($boxId && app("MaterialBoxService")->checkUsableBox($boxId))$this->success(["status"=>$exe($boxId),"amount"=>$amount-request("amount")]);
-
-        $commodity = Commodity::query()->find(request("commodity_id"));
-        if (!$commodity)$this->error("商品在WAS丢失");
-        $models = app("MaterialBoxModelService")->getModelSortedByOwner($commodity->owner_id);
-        $models->load(["commodity"=>function($query)use($commodity){
-            $query->where("commodity_id",$commodity->id);
-        }]);
-        //获取料箱
-        if ($boxId){
-            $blacklist = [$boxId];
-            $boxId = null;
-            //料箱存在且不可用
-            /** @var \Illuminate\Database\Eloquent\Collection $models */
-            foreach ($models as $model){
-                if (!$model->commodity)continue;
-                //料箱不可用寻找新料箱
-                $result = app("StorageService")->getMaxAvailableHalfBoxLocation($model->commodity, request("lotNum"), $blacklist);
-                while ($result){
-                    $materialBox = MaterialBox::query()->where("code",$result->locationid)->first();
-                    //料箱可用并且数量符合本次半箱数量 跳出
-                    if ($materialBox && app("MaterialBoxService")->checkUsableBox($materialBox->id)
-                        && $result->qty>=request("amount"))$this->success(["status"=>$exe($materialBox->id),"amount"=>$amount-request("amount")]);
-                    else if ($materialBox)$blacklist[] = $materialBox->id;
-                    //否则黑名单此料箱继续查找 直至料箱为空
-                    $result = app("StorageService")->getMaxAvailableHalfBoxLocation($model->commodity, request("lotNum"), $blacklist);
-                }
-            }
+        $key = "CACHE_SHELF_CALL_".Auth::id();
+        if (Cache::has($key)){
+            list($locationAdd,$collectionAdd) = Cache::get($key);
+            $location = $locationAdd->merge($location);
+            $collection = $collectionAdd->merge($collection);
         }
-        //料箱不存在且该商品有过入库记录 拿取空箱
-        if (!$modelId){
-            $box = null;
-            foreach ($models as $model){
-                if (!$model->commodity)continue;
-                $box = app("MaterialBoxService")->getAnEmptyBox($model);
-                if($box)break;
-            }
-        }else $box = app("MaterialBoxService")->getAnEmptyBox(MaterialBoxModel::query()->find($modelId));
-        if (!$box)$this->error("无可用料箱");
-        $this->success(["status"=>$exe($box->id),"amount"=>$amount-request("amount")]);
+        return Cache::forever($key,[$location,$collection]);
+    }
+
+    public function callRobot()
+    {
+        /** @var ForeignHaiRoboticsService $service */
+        $service = app("ForeignHaiRoboticsService");
+        $key = "CACHE_SHELF_CALL_".Auth::id();
+        list($location,$collection) = Cache::get($key);
+        if ($location->count()==0||$collection->count()==0)$this->error("没有可执行任务");
+        $res = $service->fetchGroup_multiLocation($location,$collection,'','立架出至缓存架');
+        if (!$res)$this->error("呼叫失败,海柔拒绝任务");
+        $this->success();
     }
 
     /**

+ 84 - 3
app/Http/Controllers/TestController.php

@@ -2,6 +2,8 @@
 
 namespace App\Http\Controllers;
 
+use App\Commodity;
+use App\CommodityMaterialBoxModel;
 use App\Components\AsyncResponse;
 use App\Components\ErrorPush;
 use App\ErrorTemp;
@@ -63,17 +65,96 @@ class TestController extends Controller
         $response = Http::post(config('api.haiq.storage.light'), $params);
         return json_decode($response->body());
     }
-    private $key = "CACHE_SHELF_AVAILABLE";
+    private function checkHaiQ(array $boxCodes)
+    {
+        $haiBoxes = DB::connection("mysql_haiRobotics")->table("ks_bin")
+            ->where("status",1)->whereIn("ks_bin_code",$boxCodes)->get();
+        if ($haiBoxes->count()==0)return array(null,null);
+        $codes = [];
+        $haiBoxes->each(function ($haiBox)use(&$codes){$codes[$haiBox->ks_bin_code] = true;});
+        $haiBoxes = DB::connection("mysql_haiRobotics_ess")->table("ks_ess_task_detail")
+            ->whereIn("bin_code",$boxCodes)
+            ->whereNotIn("status",[0,4])->get();
+        $notCodes = [];
+        $haiBoxes->each(function ($haiBox)use(&$notCodes){$notCodes[$haiBox->bin_code] = true;});
+        return array($codes,$notCodes);
+    }
+    public function getModelAvailableBox(int $modelId, bool $sqlQuery = false, array $blacklist = [])
+    {
+        $query = MaterialBox::query()->where("material_box_model_id",$modelId);
+        $boxes = $query->whereNotIn("id",MaterialBox::query()->where("material_box_model_id",$modelId)->select("id")
+            ->whereHas("performTask"));
+        if ($blacklist)$boxes = $boxes->whereNotIn("id",$blacklist);
+        $boxes = $boxes->get();
+        //筛选下海柔可用箱
+        list($codes,$notCodes) = $this->checkHaiQ(array_column($boxes->toArray(),"code"));
+        if (!$codes)$boxes = new \Illuminate\Database\Eloquent\Collection();
+        $boxes = $boxes->filter(function ($box)use($codes,$notCodes){
+            if (!isset($codes[$box->code]) || isset($notCodes[$box->code]))return false;
+            return true;
+        });
+
+        if (!$sqlQuery)return $boxes;
+        if ($boxes->count()==0)return array(null,null);
+        $boxCodes = "";
+        $map = [];
+        foreach ($boxes as $box){
+            $boxCodes .= "'".$box->code."',";
+            $map[$box->code] = $box->id;
+        }
+        return array(rtrim($boxCodes,","),$map);
+    }
     public function test()
     {
-        $s = new StationService();
-        dd($s->getCacheShelf(true,true));
+        $a = collect(["a"]);
+        $b = collect(["b"]);
+        dd($a->merge($b));
+        $lotNum = 'LT00551703';
+        $commodity = Commodity::query()->find(593292);
+        /** @var \Illuminate\Database\Eloquent\Collection $models */
+        $models = app("MaterialBoxModelService")->getModelSortedByOwner($commodity->owner_id);
+        $models->load(["commodity"=>function($query)use($commodity){
+            $query->where("commodity_id",$commodity->id);
+        }]);
+        $models = $models->whereNotNull("commodity");
+        if ($models->count()==0)$this->success(["status"=>false,"commodityId"=>$commodity->id]);
+
+
+        $sql = <<<SQL
+SELECT LOCATIONID,QTY FROM INV_LOT_LOC_ID WHERE LOTNUM = '{$lotNum}'
+AND LOCATIONID LIKE 'IDE%' AND SKU = '{$commodity->sku}' AND TRACEID = '*' AND QTY > 0 AND QTY > 0 ORDER BY QTY
+SQL;
+        $invs = DB::connection("oracle")->select(DB::raw($sql));
+        if ($invs){
+            $map = [];
+            $codes = [];
+            foreach ($invs as $inv){
+                $map[$inv->locationid] = $inv->qty;
+                $codes[] = $inv->locationid;
+            }
+            $modelMap = [];
+            $orderBy = "CASE material_box_model_id ";
+            foreach ($models as $key=>$model){
+                $orderBy .= 'WHEN '.$model->id." THEN ".$key;
+                $modelMap[$model->id] = $model->commodity->maximum;
+            }
+            $orderBy.= " END";
+            $boxes = MaterialBox::query()->whereIn("code",$codes)->orderByRaw($orderBy)->get();
+            foreach ($boxes as $box){
+                if ($modelMap[$box->material_box_model_id]<=$map[$box->code])continue;
+                $num = $modelMap[$box->material_box_model_id]-$map[$box->code];
+                dump([$box,$num]);
+            }
+        }
+
 
     }
 
     //快递称重 生成历史数据
     public function addRecord(Request $request)
     {
+        ini_set('max_execution_time',-1);
+        OrderPackageCountingRecord::query()->truncate();
         $start =  Carbon::parse(request("month"))->startOfMonth();
         $end = Carbon::parse(request('month'))->endOfMonth();
 

+ 1 - 1
app/Services/MaterialBoxService.php

@@ -65,7 +65,7 @@ sql;
         return null;
     }
 
-    private function checkHaiQ(array $boxCodes)
+    public function checkHaiQ(array $boxCodes)
     {
         $haiBoxes = DB::connection("mysql_haiRobotics")->table("ks_bin")
             ->where("status",1)->whereIn("ks_bin_code",$boxCodes)->get();

+ 3 - 2
app/Services/StationTaskMaterialBoxService.php

@@ -179,7 +179,6 @@ class StationTaskMaterialBoxService
                     $stationTaskMaterialBox->materialBox->update();
                     $stationTaskMaterialBox->loadMissing("station");    //提前加载站,后续都需要站信息来处理
                     $this->storageService->putCacheShelf($stationTaskMaterialBox);
-                    $this->storageService->releaseOccupation($stationTaskMaterialBox); //释放库位占用
                     break;
                 default:;
             }
@@ -206,11 +205,12 @@ class StationTaskMaterialBoxService
     /**
      * 取出料箱通知
      *
-     * @param $stationTaskMaterialBox
+     * @param StationTaskMaterialBox|\stdClass $stationTaskMaterialBox
      * @throws \Exception
      */
     function markHasTaken($stationTaskMaterialBox)
     {
+        $stationTaskMaterialBox->loadMissing("station");
         $this->instant($this->cacheShelfService,'CacheShelfService');
         //维护缓存架可用度
         $map = Cache::get("CACHE_SHELF_MAPPING",function (){return [];});
@@ -221,6 +221,7 @@ class StationTaskMaterialBoxService
             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);
+            app("StationService")->locationFreed($stationTaskMaterialBox->station->code,$stationTaskMaterialBox->material_box_id);
         }
     }
 

+ 3 - 14
app/Services/StorageService.php

@@ -37,8 +37,8 @@ class StorageService
         try{
             $stationTaskMaterialBox->loadMissing("station");
             //如果为半箱位置 清理原有任务
-            if ($stationTaskMaterialBox->station && app("StationService")->isHalfBoxLocation($stationTaskMaterialBox->station)){
-                app("StationService")->locationFreed($stationTaskMaterialBox->station->code,$stationTaskMaterialBox->material_box_id);
+            if (!$stationTaskMaterialBox->station)return;
+            if (app("StationService")->isHalfBoxLocation($stationTaskMaterialBox->station)){
                 //清除海柔库位信息
                 $this->clearTask([$stationTaskMaterialBox->station->code]);
                 $stationId = $stationTaskMaterialBox->station_id;
@@ -97,7 +97,7 @@ class StorageService
                     app("CacheShelfService")->lightUp($stationTaskMaterialBox->station->code,'2','0',$options);
                     Cache::forget("CACHE_SHELF_OCCUPANCY_{$stationTaskMaterialBox->station->id}");//关闭无限亮灯
                 }
-            }
+            }else app("StationService")->locationFreed($stationTaskMaterialBox->station->code); //释放库位占用
             DB::commit();
         }catch (\Exception $e){
             DB::rollBack();
@@ -105,17 +105,6 @@ class StorageService
         }
     }
 
-    /**
-     * 释放库位占用
-     *
-     * @param StationTaskMaterialBox|\stdClass $stationTaskMaterialBox
-     */
-    public function releaseOccupation($stationTaskMaterialBox)
-    {
-        if (!app("StationService")->isHalfBoxLocation($stationTaskMaterialBox->station))return;
-        app("StationService")->locationFreed($stationTaskMaterialBox->station->code);
-    }
-
     /**
      * 检查临时事务标记处理一些特殊情况
      *

+ 15 - 1
resources/views/store/inStorage/halfChestStorage.blade.php

@@ -33,8 +33,13 @@
                             <strong>@{{ errors.amount[0] }}</strong>
                         </span>
                     </div>
+                    <div class="form-group row">
+                        <label for="call" class="col-sm-2 col-3 text-right">手动呼叫:</label>
+                        <input type="checkbox" style="top: 5px" class="switch" id="call" v-model="info.call">
+                    </div>
                     <div class="input-group row mt-5">
-                        <button type="submit" id="submit" class="btn btn-success offset-2 col-8" @click="checkInfo()">提交</button>
+                        <button type="submit" id="submit" class="btn btn-success offset-3 col-6" @click="checkInfo()">提交</button>
+                        <button type="button" class="btn btn-sm btn-info col-2 text-white offset-1" @click="callRobot()">手动呼叫</button>
                     </div>
                 </div>
             </div>
@@ -177,6 +182,8 @@
                         }
                         this.info = {track:this.info.track};
                         this.errors = {};
+                        let element = document.getElementById("barCode");
+                        if (element)element.focus();
                         return res.amount==0 ? "调取料箱成功!" : "空箱不足,剩余”"+res.amount+"“未上架";
                     });
                 },
@@ -282,6 +289,13 @@
                     this.info.maximum = this.lotMap[this.lots[index].lotnum];
                     $("#lotModal").modal("hide");
                 },
+                callRobot(){
+                    window.tempTip.postBasicRequest("{{url('store/inStorage/callRobot')}}",{},()=>{
+                        this.info = {};
+                        let element = document.getElementById("track");
+                        if (element)element.focus();
+                    });
+                }
             },
         });
     </script>

+ 1 - 0
routes/web.php

@@ -489,6 +489,7 @@ Route::group(['middleware'=>'auth'],function ($route){
             Route::post('settingCommodityMaximum','StorageController@settingCommodityMaximum');
             Route::post('checkTask','StorageController@checkTask');
             Route::post('changeAsnRule','StorageController@changeAsnRule');
+            Route::post('callRobot','StorageController@callRobot');
         });
         Route::group(['prefix'=>'handInStorage'],function() {
             Route::get('receive',function (){return view('store.handInStorage.receive');});//收货页面