UpdatePickZone.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. namespace App\Imports;
  3. use App\OracleDOCOrderDetail;
  4. use App\Services\LogService;
  5. use Carbon\Carbon;
  6. use Illuminate\Database\Eloquent\Builder;
  7. use Illuminate\Support\Collection;
  8. use Illuminate\Support\Facades\Auth;
  9. use Illuminate\Support\Facades\Cache;
  10. use Illuminate\Support\Facades\DB;
  11. use Maatwebsite\Excel\Concerns\ToCollection;
  12. use Maatwebsite\Excel\Concerns\WithHeadingRow;
  13. use Maatwebsite\Excel\Imports\HeadingRowFormatter;
  14. HeadingRowFormatter::default('none');
  15. class UpdatePickZone implements ToCollection,WithHeadingRow
  16. {
  17. /**
  18. * @param Collection $collection
  19. * @return bool
  20. * @throws
  21. */
  22. public function collection(Collection $collection)
  23. {
  24. $row = $collection->first();
  25. $headers = ["订单编号","商品条码","数量","生产日期","失效日期"];
  26. foreach ($headers as $header){
  27. if (!isset($row[$header])){
  28. Cache::put("commodityAssign",["success"=>false, "data"=>"表头不存在“".$header."”"],86400);
  29. return false;
  30. }
  31. }
  32. $errors = [];
  33. $ids = [];
  34. foreach ($collection as $index=>$item){
  35. if ($item["生产日期"]){
  36. if (is_numeric($item["生产日期"]))$item["生产日期"] = formatExcelDate($item["生产日期"]);
  37. else{
  38. try{
  39. $item["生产日期"]=Carbon::parse($item["生产日期"])->format('Y-m-d');
  40. }catch (\Exception $e){
  41. $errors[] = "第“" . ($index + 2) . "”生产日期无法识别";
  42. continue;
  43. }
  44. }
  45. }
  46. if ($item["失效日期"]){
  47. if (is_numeric($item["失效日期"]))$item["失效日期"] = formatExcelDate($item["失效日期"]);
  48. else{
  49. try{
  50. $item["失效日期"]=Carbon::parse($item["失效日期"])->format('Y-m-d');
  51. }catch (\Exception $e){
  52. $errors[] = "第“" . ($index + 2) . "”失效日期无法识别";
  53. continue;
  54. }
  55. }
  56. }
  57. if (!$item["订单编号"]){
  58. $errors[] = "第“" . ($index + 2) . "”行订单编号为空";
  59. continue;
  60. }
  61. if (!$item["商品条码"]){
  62. $errors[] = "第“" . ($index + 2) . "”行商品条码为空";
  63. continue;
  64. }
  65. if (!$item["生产日期"] && !$item["失效日期"]){
  66. $errors[] = "第“" . ($index + 2) . "”行不存在日期";
  67. continue;
  68. }
  69. $detail = OracleDOCOrderDetail::query()->select("customerid","sku","orderno","orderlineno")
  70. ->where("orderno",$item["订单编号"])
  71. ->whereHas("sku",function ($query)use($item){
  72. /** @var Builder $query */
  73. $query->where("alternate_sku1",$item["商品条码"]);
  74. })->first();
  75. if (!$detail){
  76. $errors[] = "第“" . ($index + 2) . "”行未知订单商品";
  77. continue;
  78. }
  79. $sql = "select BAS_ZONE.DESCR,INV_LOT_LOC_ID.LOCATIONID,INV_LOT_LOC_ID.LOTNUM,BAS_LOCATION.PICKZONE,(INV_LOT_LOC_ID.QTY-INV_LOT_LOC_ID.QTYALLOCATED-QTYONHOLD-QTYRPOUT-QTYMVOUT) AS qty from INV_LOT_ATT LEFT JOIN
  80. INV_LOT_LOC_ID ON INV_LOT_ATT.LOTNUM = INV_LOT_LOC_ID.LOTNUM LEFT JOIN BAS_LOCATION ON INV_LOT_LOC_ID.LOCATIONID = BAS_LOCATION.LOCATIONID
  81. LEFT JOIN BAS_ZONE ON BAS_LOCATION.PICKZONE = BAS_ZONE.ZONE
  82. where INV_LOT_ATT.LOTNUM in (select LOTNUM from INV_LOT_LOC_ID where CUSTOMERID = ? AND SKU = ? GROUP BY LOTNUM)";
  83. $bindings = [$detail->customerid,$detail->sku];
  84. if ($item["生产日期"]){
  85. $sql .= " AND LOTATT01 = ?";
  86. $bindings[] = $item["生产日期"];
  87. }else $sql .= " AND LOTATT01 IS NULL";
  88. if ($item["失效日期"]){
  89. $sql .= " AND LOTATT02 = ?";
  90. $bindings[] = $item["失效日期"];
  91. }else $sql .= " AND LOTATT02 IS NULL";
  92. $lots = DB::connection("oracle")->select(DB::raw($sql),$bindings);
  93. if (!$lots){
  94. $errors[] = "第“" . ($index + 2) . "”行未找到库位";
  95. continue;
  96. }
  97. $result = null;
  98. if (count($lots) == 1)$result = $lots[0];
  99. else {
  100. $zone = ["存储","拣货","虚拟"];
  101. $zones = [[],[],[]];
  102. foreach ($lots as $lot){
  103. foreach ($zone as $ind=>$str){
  104. if (mb_strpos($lot->descr,$str) !== false){
  105. $zones[$ind][] = $lot;
  106. break;
  107. }
  108. }
  109. }
  110. foreach ($zones as $zl){
  111. $result = $this->matchingMax($zl,$item["数量"]);
  112. if ($result)break;
  113. }
  114. if (!$result){
  115. foreach ($zones as $zl){
  116. $result = $this->matchingMin($zl,$item["数量"]);
  117. if ($result)break;
  118. }
  119. }
  120. }
  121. if ($result){
  122. try{
  123. $sql = "UPDATE DOC_ORDER_DETAILS SET LOTNUM = ?,PICKZONE = ?,KITREFERENCENO = ?,D_EDI_09 = ?,D_EDI_10 = ? WHERE ORDERNO = ? AND ORDERLINENO = ?";
  124. DB::connection("oracle")->update(DB::raw($sql),[$result->lotnum,$result->pickzone,'0','0','0',$detail->orderno,$detail->orderlineno]);
  125. LogService::log(__METHOD__,"SUCCESS-指定效期分配修改库位",json_encode($detail)." | ".json_encode($result));
  126. $order = app("OrderService")->first(["code"=>$item["订单编号"]]);
  127. if (!$order){
  128. $errors[] = "第“" . ($index + 2) . "”行已成功修改FLUX库位但在本地未找到订单";
  129. continue;
  130. }
  131. $barcode = app("CommodityBarcodeService")->first(["code"=>$item["商品条码"]]);
  132. if (!$barcode){
  133. $errors[] = "第“" . ($index + 2) . "”行已成功修改FLUX库位但在本地未找到条码";
  134. continue;
  135. }
  136. $model = app("OrderCommodityAssignService")->create([
  137. "order_id" => $order->id,
  138. "commodity_id" => $barcode->commodity_id,
  139. "amount" => $item["数量"],
  140. "produced_at" => $item["生产日期"],
  141. "valid_at" => $item["失效日期"],
  142. "batch_number" => $result->lotnum,
  143. "location" => $result->locationid,
  144. "region" => $result->pickzone,
  145. "user_id" => Auth::id(),
  146. ]);
  147. LogService::log(__METHOD__,"SUCCESS-生成配置记录",json_encode($model));
  148. $ids[] = $model->id;
  149. }catch (\Exception $e){
  150. LogService::log(__METHOD__,"ERROR-指定效期分配修改库位",json_encode($detail)." | ".json_encode($result));
  151. }
  152. }else $errors[] = "第“" . ($index + 2) . "”行未找到可分配库位";
  153. }
  154. $assigns = app("OrderCommodityAssignService")->get(["id"=>$ids]);
  155. $models = [];
  156. foreach ($assigns as $assign){
  157. $models[] = [
  158. "orderNumber" => $assign->order ? $assign->order->code : '',
  159. "barcode" => $assign->commodity ? $assign->commodity->barcode : '',
  160. "amount" => $assign->amount,
  161. "producedAt" => $assign->produced_at,
  162. "validAt" => $assign->valid_at,
  163. "batchNumber" => $assign->batch_number,
  164. "location" => $assign->location,
  165. "region" => $assign->region,
  166. "createdAt" => $assign->created_at,
  167. "userName" => $assign->user ? $assign->user->name : 'system',
  168. ];
  169. }
  170. Cache::put("commodityAssign",["success"=>true,"data"=>$models,"errors"=>$errors]);
  171. }
  172. private function matchingMax($lots, $amount)
  173. {
  174. if (!$lots) return null;
  175. $max = null;
  176. $map = [];
  177. foreach ($lots as $i => $l){
  178. $qty = (int)$l->qty;
  179. $map[$qty] = $i;
  180. if (($qty >= $amount && $qty<=$max) || $max===null)$max = $qty;
  181. }
  182. if ($max !== null && $max>=$amount)return $lots[$map[$max]];
  183. return null;
  184. }
  185. private function matchingMin($lots, $amount)
  186. {
  187. if (!$lots) return null;
  188. $min = null;
  189. $map = [];
  190. foreach ($lots as $i => $l){
  191. $qty = (int)$l->qty;
  192. $map[$qty] = $i;
  193. if (($qty < $amount && $qty>=$min) || $min===null)$min = $qty;
  194. }
  195. if ($min !== null)return $lots[$map[$min]];
  196. return null;
  197. }
  198. }