MaterialBoxService.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. * @param int $multi
  19. *
  20. * @return MaterialBox|null|array
  21. */
  22. public function getAnEmptyBox(MaterialBoxModel $model,array $blacklist = [], int $multi = 1)
  23. {
  24. $id = 0;
  25. $tarBoxes = [];
  26. while (true){
  27. //检测WAS
  28. $boxes = MaterialBox::query()->select('id',"code")
  29. ->whereNotIn("id",$blacklist)
  30. ->where("id",">",$id)->where("code","like","IDE%")
  31. /*->where("status",4)*/->limit(100)->orderBy("id")
  32. ->whereNotIn("id",StationTaskMaterialBox::query()->select("material_box_id")
  33. ->whereNotIn("status",["完成","取消"])
  34. ->where("material_box_model_id",$model->id)->groupBy("material_box_id"));
  35. $boxes = $boxes->get();
  36. if ($boxes->count()==0)break;
  37. $id = $boxes[count($boxes)-1]->id;
  38. $boxCodes = array_column($boxes->toArray(),"code");
  39. //检测海柔的有效料箱并剔除有任务待处理的料箱
  40. list($codes,$notCodes) = $this->checkHaiQ($boxCodes);
  41. if (!$codes)continue;
  42. //剔除FLUX已有库存并且库位内种类超出的料箱
  43. $ides = [];
  44. $str = "(";
  45. foreach ($boxes as $box){
  46. if (!isset($codes[$box->code]) || isset($notCodes[$box->code]))continue;
  47. $str .= "'".$box->code."',";
  48. $ides[$box->code] = $box;
  49. }
  50. if (!$ides)continue;
  51. $str = rtrim($str,",").")";
  52. $sql = <<<sql
  53. 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
  54. LOCATIONID HAVING (COUNT(*)>={$model->maximum_kind})
  55. sql;
  56. foreach (DB::connection("oracle")->select(DB::raw($sql)) as $item)unset($ides[$item->locationid]);
  57. foreach ($ides as $box){
  58. $tarBoxes[] = $box;
  59. $multi--;
  60. if (!$multi)break 2;
  61. }
  62. }
  63. $len = count($tarBoxes);
  64. return $len==1 ? $tarBoxes[0] : ($len==0 ? null : $tarBoxes);
  65. }
  66. public function checkHaiQ(array $boxCodes)
  67. {
  68. $haiBoxes = DB::connection("mysql_haiRobotics")->table("ks_bin")
  69. ->where("status",1)->whereIn("ks_bin_code",$boxCodes)->get();
  70. if ($haiBoxes->count()==0)return array(null,null);
  71. $codes = [];
  72. $haiBoxes->each(function ($haiBox)use(&$codes){$codes[$haiBox->ks_bin_code] = true;});
  73. $haiBoxes = DB::connection("mysql_haiRobotics_ess")->table("ks_ess_task_detail")
  74. ->whereIn("bin_code",$boxCodes)
  75. ->whereNotIn("status",[0,4])->get();
  76. $notCodes = [];
  77. $haiBoxes->each(function ($haiBox)use(&$notCodes){$notCodes[$haiBox->bin_code] = true;});
  78. return array($codes,$notCodes);
  79. }
  80. /**
  81. * 获取所有者排序的空盒子
  82. *
  83. * @param integer|null $ownerId
  84. * @param array $blacklist
  85. * @param int $multi
  86. *
  87. * @return MaterialBox|null|array
  88. */
  89. public function getAnEmptyBoxSortedByOwner(?int $ownerId=null, array $blacklist=[], int $multi = 1)
  90. {
  91. $models = app("MaterialBoxModelService")->getModelSortedByOwner($ownerId);
  92. $tarBoxes = [];
  93. foreach ($models as $model){
  94. $box = $this->getAnEmptyBox($model,$blacklist,$multi);
  95. if (!$box)continue;
  96. if (is_array($box)){
  97. $tarBoxes = array_merge($tarBoxes,$box);
  98. $multi -= count($box);
  99. }else{
  100. $tarBoxes[] = $box;
  101. $multi--;
  102. }
  103. if (!$multi)break;
  104. }
  105. $len = count($tarBoxes);
  106. return $len==1 ? $tarBoxes[0] : ($len==0 ? null : $tarBoxes);
  107. }
  108. /**
  109. * 检查可用料箱
  110. *
  111. * @param integer $boxId
  112. *
  113. * @return bool
  114. */
  115. public function checkUsableBox(int $boxId):bool
  116. {
  117. /** @var MaterialBox|\stdClass $box */
  118. if (StationTaskMaterialBox::query()->select(DB::raw(1))->whereNotIn("status",['完成','取消'])->where("material_box_id",$boxId)->first())return false;
  119. return true;
  120. }
  121. /**
  122. * 获取某个型号下的可用料箱
  123. *
  124. * @param integer $modelId
  125. * @param bool $sqlQuery
  126. * @param array $blacklist
  127. *
  128. * @return Collection|string|null|array
  129. */
  130. public function getModelAvailableBox(int $modelId, bool $sqlQuery = false, array $blacklist = [])
  131. {
  132. $query = MaterialBox::query()->where("material_box_model_id",$modelId)->where("status",4);
  133. $boxes = $query->whereNotIn("id",$query->select("id")->whereHas("performTask"));
  134. if ($blacklist)$boxes = $boxes->whereNotIn("id",$blacklist);
  135. $boxes = $boxes->get();
  136. //筛选下海柔可用箱
  137. list($codes,$notCodes) = $this->checkHaiQ(array_column($boxes->toArray(),"code"));
  138. if (!$codes)$boxes = new \Illuminate\Database\Eloquent\Collection();
  139. $boxes = $boxes->filter(function ($box)use($codes,$notCodes){
  140. if (!isset($codes[$box->code]) || isset($notCodes[$box->code]))return false;
  141. return true;
  142. });
  143. if (!$sqlQuery)return $boxes;
  144. if ($boxes->count()==0)return array(null,null);
  145. $boxCodes = "";
  146. $map = [];
  147. foreach ($boxes as $box){
  148. $boxCodes .= "'".$box->code."',";
  149. $map[$box->code] = $box->id;
  150. }
  151. return array(rtrim($boxCodes,","),$map);
  152. }
  153. /**
  154. * 检查料箱规范
  155. *
  156. * @param string|null $code
  157. *
  158. * @return bool
  159. */
  160. public function checkBoxNorm(?string $code):bool
  161. {
  162. if (!$code)return false;
  163. foreach (config("haiRou.box.prefix") as $prefix){
  164. if (substr($code,0,strlen($prefix))==$prefix)return true;
  165. }
  166. return false;
  167. }
  168. }