MaterialBoxService.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. namespace App\Services;
  3. use App\MaterialBox;
  4. use App\MaterialBoxModel;
  5. use App\StationTaskMaterialBox;
  6. use App\Traits\ServiceAppAop;
  7. use Illuminate\Support\Collection;
  8. use Illuminate\Support\Facades\DB;
  9. class MaterialBoxService
  10. {
  11. use ServiceAppAop;
  12. protected $modelClass=MaterialBox::class;
  13. /**
  14. * 获取一个空料箱
  15. *
  16. * @param MaterialBoxModel|\stdClass $model
  17. * @param array $blacklist
  18. *
  19. * @return MaterialBox|null
  20. */
  21. public function getAnEmptyBox(MaterialBoxModel $model,array $blacklist = []):?MaterialBox
  22. {
  23. $id = 0;
  24. while (true){
  25. //检测WAS
  26. $boxes = MaterialBox::query()->select('id',"code")
  27. ->whereNotIn("id",$blacklist)
  28. ->where("id",">",$id)->where("code","like","IDE%")
  29. ->where("status",4)->limit(50)->orderBy("id")
  30. ->whereNotIn("id",StationTaskMaterialBox::query()->select("material_box_id")
  31. ->whereNotIn("status",["完成","取消"])
  32. ->where("material_box_model_id",$model->id)->groupBy("material_box_id"));
  33. $boxes = $boxes->get();
  34. if ($boxes->count()==0)break;
  35. $id = $boxes[count($boxes)-1]->id;
  36. $boxCodes = array_column($boxes->toArray(),"code");
  37. //检测海柔的有效料箱并剔除有任务待处理的料箱
  38. list($codes,$notCodes) = $this->checkHaiQ($boxCodes);
  39. if (!$codes)continue;
  40. //剔除FLUX已有库存并且库位内种类超出的料箱
  41. $ides = [];
  42. $str = "(";
  43. foreach ($boxes as $box){
  44. if (!isset($codes[$box->code]) || isset($notCodes[$box->code]))continue;
  45. $str .= "'".$box->code."',";
  46. $ides[$box->code] = $box;
  47. }
  48. if (!$ides)continue;
  49. $str = rtrim($str,",").")";
  50. $sql = <<<sql
  51. SELECT LOCATIONID FROM (SELECT LOCATIONID FROM (SELECT LOCATIONID,SUM(QTY+QTYPA) qty FROM INV_LOT_LOC_ID WHERE LOCATIONID IN {$str} GROUP BY LOCATIONID,LOTNUM,CUSTOMERID,SKU) where qty>0) GROUP BY
  52. LOCATIONID HAVING (COUNT(*)>={$model->maximum_kind})
  53. sql;
  54. foreach (DB::connection("oracle")->select(DB::raw($sql)) as $item)unset($ides[$item->locationid]);
  55. if ($ides)return current($ides);
  56. }
  57. return null;
  58. }
  59. public function checkHaiQ(array $boxCodes)
  60. {
  61. $haiBoxes = DB::connection("mysql_haiRobotics")->table("ks_bin")
  62. ->where("status",1)->whereIn("ks_bin_code",$boxCodes)->get();
  63. if ($haiBoxes->count()==0)return array(null,null);
  64. $codes = [];
  65. $haiBoxes->each(function ($haiBox)use(&$codes){$codes[$haiBox->ks_bin_code] = true;});
  66. $haiBoxes = DB::connection("mysql_haiRobotics_ess")->table("ks_ess_task_detail")
  67. ->whereIn("bin_code",$boxCodes)
  68. ->whereNotIn("status",[0,4])->get();
  69. $notCodes = [];
  70. $haiBoxes->each(function ($haiBox)use(&$notCodes){$notCodes[$haiBox->bin_code] = true;});
  71. return array($codes,$notCodes);
  72. }
  73. /**
  74. * 获取所有者排序的空盒子
  75. *
  76. * @param integer|null $ownerId
  77. * @param array $blacklist
  78. *
  79. * @return MaterialBox|null
  80. */
  81. public function getAnEmptyBoxSortedByOwner(?int $ownerId=null, array $blacklist=[]):?MaterialBox
  82. {
  83. $models = app("MaterialBoxModelService")->getModelSortedByOwner($ownerId);
  84. foreach ($models as $model){
  85. $box = $this->getAnEmptyBox($model,$blacklist);
  86. if ($box)return $box;
  87. }
  88. return null;
  89. }
  90. /**
  91. * 检查可用料箱
  92. *
  93. * @param integer $boxId
  94. *
  95. * @return bool
  96. */
  97. public function checkUsableBox(int $boxId):bool
  98. {
  99. /** @var MaterialBox|\stdClass $box */
  100. if (StationTaskMaterialBox::query()->select(DB::raw(1))->whereNotIn("status",['完成','取消'])->where("material_box_id",$boxId)->first())return false;
  101. return true;
  102. }
  103. /**
  104. * 获取某个型号下的可用料箱
  105. *
  106. * @param integer $modelId
  107. * @param bool $sqlQuery
  108. * @param array $blacklist
  109. *
  110. * @return Collection|string|null|array
  111. */
  112. public function getModelAvailableBox(int $modelId, bool $sqlQuery = false, array $blacklist = [])
  113. {
  114. $query = MaterialBox::query()->where("material_box_model_id",$modelId)->where("status",4);
  115. $boxes = $query->whereNotIn("id",$query->select("id")->whereHas("performTask"));
  116. if ($blacklist)$boxes = $boxes->whereNotIn("id",$blacklist);
  117. $boxes = $boxes->get();
  118. //筛选下海柔可用箱
  119. list($codes,$notCodes) = $this->checkHaiQ(array_column($boxes->toArray(),"code"));
  120. if (!$codes)$boxes = new \Illuminate\Database\Eloquent\Collection();
  121. $boxes = $boxes->filter(function ($box)use($codes,$notCodes){
  122. if (!isset($codes[$box->code]) || isset($notCodes[$box->code]))return false;
  123. return true;
  124. });
  125. if (!$sqlQuery)return $boxes;
  126. if ($boxes->count()==0)return array(null,null);
  127. $boxCodes = "";
  128. $map = [];
  129. foreach ($boxes as $box){
  130. $boxCodes .= "'".$box->code."',";
  131. $map[$box->code] = $box->id;
  132. }
  133. return array(rtrim($boxCodes,","),$map);
  134. }
  135. }