MaterialBoxService.php 6.3 KB

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