UpdatePickZone.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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("DOC_ORDER_DETAILS.customerid","DOC_ORDER_DETAILS.sku","DOC_ORDER_DETAILS.orderno","DOC_ORDER_DETAILS.orderlineno","sostatus")
  70. ->where("DOC_ORDER_DETAILS.orderno",$item["订单编号"])
  71. ->whereHas("sku",function ($query)use($item){
  72. /** @var Builder $query */
  73. $query->where("alternate_sku1",$item["商品条码"]);
  74. })->leftJoin("DOC_ORDER_HEADER","DOC_ORDER_DETAILS.ORDERNO","=","DOC_ORDER_HEADER.ORDERNO")->first();
  75. if (!$detail){
  76. $errors[] = "第“" . ($index + 2) . "”行未知订单商品";
  77. continue;
  78. }
  79. if ($detail->sostatus != '00'){
  80. $errors[] = "第“" . ($index + 2) . "”行订单状态不为创建订单";
  81. continue;
  82. }
  83. $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
  84. 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
  85. LEFT JOIN BAS_ZONE ON BAS_LOCATION.PICKZONE = BAS_ZONE.ZONE
  86. where INV_LOT_ATT.LOTNUM in (select LOTNUM from INV_LOT_LOC_ID where CUSTOMERID = ? AND SKU = ? GROUP BY LOTNUM)";
  87. $bindings = [$detail->customerid,$detail->sku];
  88. if ($item["生产日期"]){
  89. $sql .= " AND LOTATT01 = ?";
  90. $bindings[] = $item["生产日期"];
  91. }else $sql .= " AND LOTATT01 IS NULL";
  92. if ($item["失效日期"]){
  93. $sql .= " AND LOTATT02 = ?";
  94. $bindings[] = $item["失效日期"];
  95. }else $sql .= " AND LOTATT02 IS NULL";
  96. $lots = DB::connection("oracle")->select(DB::raw($sql),$bindings);
  97. if (!$lots){
  98. $errors[] = "第“" . ($index + 2) . "”行未找到库位";
  99. continue;
  100. }
  101. $result = null;
  102. if (count($lots) == 1)$result = $lots[0];
  103. else {
  104. $zone = ["存储","拣货","虚拟"];
  105. $zones = [[],[],[]];
  106. foreach ($lots as $lot){
  107. foreach ($zone as $ind=>$str){
  108. if (mb_strpos($lot->descr,$str) !== false){
  109. $zones[$ind][] = $lot;
  110. break;
  111. }
  112. }
  113. }
  114. foreach ($zones as $zl){
  115. $result = $this->matchingMax($zl,$item["数量"]);
  116. if ($result)break;
  117. }
  118. if (!$result){
  119. foreach ($zones as $zl){
  120. $result = $this->matchingMin($zl,$item["数量"]);
  121. if ($result)break;
  122. }
  123. }
  124. }
  125. if ($result){
  126. try{
  127. $sql = "UPDATE DOC_ORDER_DETAILS SET LOTNUM = ?,PICKZONE = ?,KITREFERENCENO = ?,D_EDI_09 = ?,D_EDI_10 = ? WHERE ORDERNO = ? AND ORDERLINENO = ?";
  128. DB::connection("oracle")->update(DB::raw($sql),[$result->lotnum,$result->pickzone,'0','0','0',$detail->orderno,$detail->orderlineno]);
  129. LogService::log(__METHOD__,"SUCCESS-指定效期分配修改库位",json_encode($detail)." | ".json_encode($result));
  130. $order = app("OrderService")->first(["code"=>$item["订单编号"]]);
  131. if (!$order){
  132. $errors[] = "第“" . ($index + 2) . "”行已成功修改FLUX库位但在本地未找到订单";
  133. continue;
  134. }
  135. $barcode = app("CommodityBarcodeService")->first(["code"=>$item["商品条码"]]);
  136. if (!$barcode){
  137. $errors[] = "第“" . ($index + 2) . "”行已成功修改FLUX库位但在本地未找到条码";
  138. continue;
  139. }
  140. $model = app("OrderCommodityAssignService")->create([
  141. "order_id" => $order->id,
  142. "commodity_id" => $barcode->commodity_id,
  143. "amount" => $item["数量"],
  144. "produced_at" => $item["生产日期"],
  145. "valid_at" => $item["失效日期"],
  146. "batch_number" => $result->lotnum,
  147. "location" => $result->locationid,
  148. "region" => $result->pickzone,
  149. "user_id" => Auth::id(),
  150. ]);
  151. LogService::log(__METHOD__,"SUCCESS-生成配置记录",json_encode($model));
  152. $ids[] = $model->id;
  153. }catch (\Exception $e){
  154. LogService::log(__METHOD__,"ERROR-指定效期分配修改库位",json_encode($detail)." | ".json_encode($result));
  155. }
  156. }else $errors[] = "第“" . ($index + 2) . "”行未找到可分配库位";
  157. }
  158. $assigns = app("OrderCommodityAssignService")->get(["id"=>$ids]);
  159. $models = [];
  160. foreach ($assigns as $assign){
  161. $models[] = [
  162. "orderNumber" => $assign->order ? $assign->order->code : '',
  163. "barcode" => $assign->commodity ? $assign->commodity->barcode : '',
  164. "amount" => $assign->amount,
  165. "producedAt" => $assign->produced_at,
  166. "validAt" => $assign->valid_at,
  167. "batchNumber" => $assign->batch_number,
  168. "location" => $assign->location,
  169. "region" => $assign->region,
  170. "createdAt" => $assign->created_at,
  171. "userName" => $assign->user ? $assign->user->name : 'system',
  172. ];
  173. }
  174. Cache::put("commodityAssign",["success"=>true,"data"=>$models,"errors"=>$errors]);
  175. }
  176. private function matchingMax($lots, $amount)
  177. {
  178. if (!$lots) return null;
  179. $max = null;
  180. $map = [];
  181. foreach ($lots as $i => $l){
  182. $qty = (int)$l->qty;
  183. $map[$qty] = $i;
  184. if (($qty >= $amount && $qty<=$max) || $max===null)$max = $qty;
  185. }
  186. if ($max !== null && $max>=$amount)return $lots[$map[$max]];
  187. return null;
  188. }
  189. private function matchingMin($lots, $amount)
  190. {
  191. if (!$lots) return null;
  192. $min = null;
  193. $map = [];
  194. foreach ($lots as $i => $l){
  195. $qty = (int)$l->qty;
  196. $map[$qty] = $i;
  197. if (($qty < $amount && $qty>=$min) || $min===null)$min = $qty;
  198. }
  199. if ($min !== null)return $lots[$map[$min]];
  200. return null;
  201. }
  202. }