UpdatePickZone.php 9.8 KB

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