WeightService.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. <?php
  2. namespace App\Services\weight;
  3. use App\Events\WeighedEvent;
  4. use App\Http\Controllers\api\thirdPart\flux\PackageController;
  5. use App\Jobs\WeightUpdateInstantBill;
  6. use App\MeasuringMachine;
  7. use App\OracleActAllocationDetails;
  8. use App\OracleDOCOrderHeader;
  9. use App\OrderPackage;
  10. use App\Services\OrderService;
  11. use App\Waybill;
  12. use Illuminate\Database\Eloquent\Builder;
  13. use Illuminate\Database\Eloquent\Model;
  14. use Illuminate\Support\Carbon;
  15. use Illuminate\Support\Facades\DB;
  16. use Illuminate\Support\Facades\Log;
  17. class WeightService
  18. {
  19. public $weight = ''; // 重量
  20. public $length = ''; // 长
  21. public $width = ''; // 宽
  22. public $height = ''; // 高
  23. public $code = ''; // 快递单号
  24. public $weight_at = ''; // 称重时间
  25. public $hid = ''; // 称重设备id
  26. public $name = ''; // 名称
  27. public function new(array $params): array
  28. {
  29. $params = $this->conversionParams($params);
  30. return $this->weightOrderPackage($params);
  31. }
  32. /**
  33. * 参数转换
  34. * @param array $params
  35. * @return array
  36. */
  37. public function conversionParams(array $params): array
  38. {
  39. return $params;
  40. }
  41. /**
  42. * 包裹称重
  43. * @param array $params
  44. * @return array
  45. */
  46. public function weightOrderPackage(array $params): array
  47. {
  48. // 2.获取快递单号
  49. $logistic_number = $this->getCodeValue($params);
  50. if (!$logistic_number) return $this->getLogisticNumberIsNullMessage($params);
  51. // 3、获取称重设备
  52. $measuringMachine = $this->getMeasuringMachine($params);
  53. /** @var OrderPackage $orderPackage */
  54. $orderPackage = $this->getOrderPackageByCode($logistic_number);
  55. // 4、快递单号对应的OrderPackage
  56. if (is_null($orderPackage)) {
  57. /** @var OracleDOCOrderHeader $orderHeader */
  58. $orderHeader = $this->findOrderHeaderByLogisticNumber($logistic_number);
  59. if (is_null($orderHeader)) {
  60. return $this->getNotFindOrderHeaderMessage($params, $orderPackage);
  61. }
  62. try {
  63. $order = $this->createOrderByOrderHeader($orderHeader);
  64. $orderPackage = $this->createOrderPackage($params, $measuringMachine, $order);
  65. } catch (\Exception $e) {
  66. return $this->getWriteWasFailMessage($params, $orderPackage);
  67. }
  68. }
  69. // 5、更新包裹信息
  70. try {
  71. $bool = $this->updateOrderPackage($orderPackage, $params, $measuringMachine);
  72. } catch (\Exception $e) {
  73. $result = DB::select('select * from information_schema.innodb_trx');
  74. Log::warning("包裹称重",["message"=>json_encode($result),"param"=>json_encode($result)]);
  75. return $this->getWeightMessage($orderPackage, $e->getMessage());
  76. }
  77. // 6、称重时间
  78. if ($bool) $this->afterApply($orderPackage);
  79. else {
  80. app('LogService')->log(__METHOD__, $this->name, '写入WAS失败! (Error)', $logistic_number, null);
  81. return $this->getUpdatePackageMessage($orderPackage);
  82. }
  83. // 7、处理波次信息 推送至WMS称重信息
  84. try {
  85. $this->activityWaveNoProcessing($orderPackage);
  86. } catch (\Exception $e) {
  87. return $this->getWeightMessage($orderPackage, $e);
  88. }
  89. return $this->getSuccessMessage($params, $orderPackage);
  90. }
  91. // region ---消息返回
  92. /**
  93. * 称重成功
  94. * @param $params
  95. * @param $orderPackage
  96. * @return array
  97. */
  98. public function getSuccessMessage($params, $orderPackage): array
  99. {
  100. return ['success' => true, 'message' => '称重成功'];
  101. }
  102. /**
  103. * 没有找到对应的包裹信息
  104. * @param $params
  105. * @param $orderPackage
  106. * @return array
  107. */
  108. public function getNotFindOrderPackageMessage($params, $orderPackage): array
  109. {
  110. return ['success' => false, 'message' => '未找打包裹信息'];
  111. }
  112. /**
  113. * 富勒信息对应快递单号错误
  114. * @param $params
  115. * @param $orderPackage
  116. * @return array
  117. */
  118. public function getNotFindOrderHeaderMessage($params, $orderPackage): array
  119. {
  120. return ['success' => false, 'message' => '富勒信息未找到'];
  121. }
  122. /**
  123. * 称重下发修改错误
  124. * @param $orderPackage
  125. * @param $e
  126. * @return array
  127. */
  128. public function getWeightMessage($orderPackage, $e): array
  129. {
  130. return ['success' => false, 'message' => $e->getMessage];
  131. }
  132. /**
  133. * 更新包裹信息异常错误返回
  134. * @param $orderPackage
  135. * @return array
  136. */
  137. public function getUpdatePackageMessage($orderPackage): array
  138. {
  139. return ['success' => false, 'message' => '更新包裹信息出现异常'];
  140. }
  141. /**
  142. * 快递单号过滤后为空
  143. * @param $params
  144. * @return array
  145. */
  146. public function getLogisticNumberIsNullMessage($params): array
  147. {
  148. return ['success' => false, 'message' => '快递单号过滤后为空'];
  149. }
  150. /**
  151. * 写入Was失败信息
  152. * @param $params
  153. * @param $orderPackage
  154. * @return array
  155. */
  156. public function getWriteWasFailMessage($params, $orderPackage): array
  157. {
  158. return ['success' => false, 'message' => '写入was失败!'];
  159. }
  160. // endregion
  161. // region ---称重完成之后的操作
  162. /**
  163. * 称重完成后的后续操作
  164. * @param OrderPackage $orderPackage
  165. */
  166. public function afterApply(OrderPackage $orderPackage)
  167. {
  168. $orderPackage->loadMissing(['order' => function ($query) {
  169. $query->with('owner', 'logistic');
  170. }, 'measuringMachine', 'paperBox']);
  171. event(new WeighedEvent($orderPackage)); // 称重信息播报
  172. dispatch(new WeightUpdateInstantBill($orderPackage)); // 及时订单
  173. if(!empty($orderPackage->order)){
  174. Waybill::setWeightByOrderCode($orderPackage->order->code,$orderPackage['weight']);
  175. }
  176. }
  177. // endregion
  178. // region ---参数获取
  179. /**
  180. * 重量
  181. * @param $params
  182. * @return mixed|null
  183. */
  184. public function getWeightValue($params)
  185. {
  186. return $this->getValue($this->weight, $params);
  187. }
  188. /**
  189. * 高
  190. * @param $params
  191. * @return mixed|null
  192. */
  193. public function getHeightValue($params)
  194. {
  195. return $this->getValue($this->height, $params);
  196. }
  197. /**
  198. * 长
  199. * @param $params
  200. * @return mixed|null
  201. */
  202. public function getLengthValue($params)
  203. {
  204. return $this->getValue($this->length, $params);
  205. }
  206. /**
  207. * 宽
  208. * @param $params
  209. * @return mixed|null
  210. */
  211. public function getWidthValue($params)
  212. {
  213. return $this->getValue($this->width, $params);
  214. }
  215. /**
  216. * 获取快递单号
  217. * @param $params
  218. * @return mixed|null
  219. */
  220. public function getCodeValue($params)
  221. {
  222. return $this->getValue($this->code, $params);
  223. }
  224. /**
  225. * 称重时间
  226. * @param $params
  227. * @return mixed|null
  228. */
  229. public function getWeightAtValue($params)
  230. {
  231. return $this->getValue($this->weight_at, $params);
  232. }
  233. /**
  234. * 获取参数
  235. * @param $name
  236. * @param $param
  237. * @return mixed|null
  238. */
  239. public function getValue($name, $param)
  240. {
  241. $names = explode(',', $name);
  242. $value = array_reduce($names, function ($data, $key) {
  243. if (isset($data[$key])) $data = $data[$key];
  244. else $data = [];
  245. return $data;
  246. }, $param);
  247. if (is_array($value) && count($value) == 0) return null;
  248. return $value;
  249. }
  250. /**
  251. * 体积参数排序
  252. * @param $params
  253. * @return array
  254. */
  255. public function getEdges($params): array
  256. {
  257. $length = $this->getLengthValue($params);
  258. $height = $this->getHeightValue($params);
  259. $width = $this->getWidthValue($params);
  260. $edges = [$length ?? 0, $width ?? 0, $height ?? 0];
  261. rsort($edges);
  262. return $edges;
  263. }
  264. // endregion
  265. // region ---包裹
  266. /**
  267. * 获取单号对应的包裹
  268. * @param $code
  269. * @return Builder|Model|object|null
  270. */
  271. public function getOrderPackageByCode($code)
  272. {
  273. return OrderPackage::query()
  274. ->with(['order' => function ($query) {
  275. /** @var Builder $query */
  276. $query->with('owner', 'logistic');
  277. }])->where('logistic_number', $code)->first();
  278. }
  279. /**
  280. * 更新包裹信息
  281. * @param OrderPackage $orderPackage
  282. * @param $params
  283. * @param $measuringMachine
  284. * @return bool
  285. */
  286. public function updateOrderPackage(OrderPackage $orderPackage, $params, $measuringMachine): bool
  287. {
  288. $edges = $this->getEdges($params);
  289. $req_date = Carbon::now()->toDateTimeString();
  290. $orderPackage['weight'] = $this->getWeightValue($params);
  291. $orderPackage['measuring_machine_id'] = $measuringMachine['id'];
  292. $orderPackage['length'] = $edges[0];
  293. $orderPackage['width'] = $edges[1];
  294. $orderPackage['height'] = $edges[2];
  295. $orderPackage['weighed_at'] = $req_date;
  296. $orderPackage['bulk'] = $edges[0] * $edges[1] * $edges[2];
  297. return $orderPackage->save();
  298. }
  299. /**
  300. * 创建包裹信息
  301. * @param $params
  302. * @param $measuringMachine
  303. * @param $order
  304. * @return Builder|Model|object|null
  305. */
  306. public function createOrderPackage($params, $measuringMachine, $order)
  307. {
  308. $weighed_at = Carbon::now()->format(Carbon::DEFAULT_TO_STRING_FORMAT);
  309. $edges = $this->getEdges($params);
  310. OrderPackage::query()->create([
  311. 'order_id' => $order->id,
  312. 'logistic_number' => $this->getCodeValue($params),
  313. 'measuring_machine_id' => $measuringMachine->id,
  314. 'weight' => $this->getWeightValue($params),
  315. 'length' => $edges[0],
  316. 'width' => $edges[1],
  317. 'height' => $edges[2],
  318. 'bulk' => $edges[0] * $edges[1] * $edges[2],
  319. 'weighed_at' => $weighed_at,
  320. 'status' => "无",
  321. ]);
  322. return $this->getOrderPackageByCode($this->getCodeValue($params));
  323. }
  324. // endregion
  325. // region ---称重设备
  326. /**
  327. * 称重机获取
  328. * @param $params
  329. * @return MeasuringMachine
  330. */
  331. public function getMeasuringMachine($params): MeasuringMachine
  332. {
  333. $hid = $this->getValue($this->hid, $params);
  334. /** @var MeasuringMachine $measuringMachine */
  335. $measuringMachine = MeasuringMachine::query()->firstOrCreate(['code' => $hid], ['name' => $hid]); // 称重设备
  336. $measuringMachine->turnOn();
  337. $measuringMachine->turnOffInMinutes(30);
  338. return $measuringMachine;
  339. }
  340. // endregion
  341. // region ---wms操作
  342. /**
  343. * 根据快递单号找到对应的WMS订单信息
  344. * @param $code
  345. * @return Builder|Model|object|null
  346. */
  347. public function findOrderHeaderByLogisticNumber($code)
  348. {
  349. $query = OracleActAllocationDetails::query()->select('OrderNO')->where('PickToTraceId', $code);
  350. $orderHeader = OracleDOCOrderHeader::query()->with('actAllocationDetails', 'oracleBASCode')->whereIn('OrderNO', $query)->first();
  351. if ($orderHeader == null) {
  352. $orderHeader = OracleDOCOrderHeader::query()->with('actAllocationDetails', 'oracleBASCode')->where('SOReference5', $code)->first();
  353. }
  354. return $orderHeader;
  355. }
  356. /**
  357. * 同步wms订单信息
  358. * @param $orderHeader
  359. * @return Builder|Model|object
  360. */
  361. public function createOrderByOrderHeader($orderHeader)
  362. {
  363. /** @var OrderService $orderService */
  364. $orderService = app(OrderService::class);
  365. $order_create_params = $orderService->getParamByOrderHeader($orderHeader);
  366. $order = $orderService->first(['code' => $orderHeader->orderno]);
  367. if ($order) return $order;
  368. $order = $orderService->createOrder($order_create_params);
  369. app('LogService')->log(__METHOD__, $this->name, ' 创建Order', json_encode($order) . " || " . $orderHeader);
  370. return $order;
  371. }
  372. /**
  373. * 活动波次处理
  374. * @param $orderPackage
  375. */
  376. public function activityWaveNoProcessing(&$orderPackage)
  377. {
  378. $fluxController = new PackageController();
  379. if ($orderPackage->isActivityBatch()) {
  380. app('LogService')->log(__METHOD__, $this->name . " 依波次号同步所有包裹", json_encode($orderPackage), null);
  381. OrderPackage::query()->where('batch_number', $orderPackage['batch_number'])->update([
  382. 'weight' => $orderPackage['weight'] ?? null,
  383. 'length' => $orderPackage['length'] ?? null,
  384. 'width' => $orderPackage['width'] ?? null,
  385. 'height' => $orderPackage['height'] ?? null,
  386. 'bulk' => $orderPackage['bulk'] ?? null,
  387. 'measuring_machine_id' => $orderPackage['measuring_machine_id'] ?? null,
  388. 'weighed_at' => $orderPackage['weighed_at'] ?? null,
  389. 'paper_box_id' => $orderPackage['paper_box_id'] ?? null,
  390. ]);
  391. $result = $fluxController->markWMSOnBatch($orderPackage['batch_number'], $orderPackage['weight']);
  392. if (!$result['result']) {
  393. $orderPackage->uploaded_to_wms = "异常";
  394. }
  395. } else {
  396. app('LogService')->log(__METHOD__, $this->name . " 写入包裹至WMS异常", json_encode($orderPackage), null);
  397. try {
  398. $result = $fluxController->accomplishToWMS($orderPackage);
  399. if ($result['result'] == 'success') $orderPackage->uploaded_to_wms = "是";
  400. else $orderPackage->uploaded_to_wms = "异常";
  401. } catch (\Exception $e) {
  402. $orderPackage->uploaded_to_wms = "否";
  403. }
  404. }
  405. $orderPackage->save();
  406. }
  407. // endregion
  408. // region ---上传快递单号处理
  409. /**
  410. * 快递单号处理
  411. *
  412. * @param $code
  413. * @return string
  414. */
  415. public function processCode($code): string
  416. {
  417. /** 如果是$code 是数组处理 */
  418. if (is_array($code)) {
  419. return $this->processCodeArr($code);
  420. }
  421. return $this->processCodeStr($code);
  422. }
  423. /**
  424. * 快递单号 array 处理
  425. *
  426. * @param array $code
  427. * @return mixed|string
  428. */
  429. public function processCodeArr(array $code): string
  430. {
  431. usort($code, function ($codeA, $codeB) {
  432. if (strlen($codeA) == strlen($codeB)) return 0;
  433. return strlen($codeA) > strlen($codeB) ? 1 : -1;
  434. });
  435. return $code[0];
  436. }
  437. /**
  438. * 快递单号 string 处理
  439. *
  440. * @param $code
  441. * @return string|null
  442. */
  443. public function processCodeStr($code): ?string
  444. {
  445. $codes = [];
  446. preg_match_all('/[\w]+/', $code, $codes);
  447. if (count($codes) == 0) return $code;
  448. $codes = array_unique(array_filter(array_shift($codes), function ($item) {
  449. return strlen($item) > 8;
  450. }));
  451. usort($codes, function ($a, $b) {
  452. if (strlen($a) == strlen($b)) return 0;
  453. return strlen($a) < strlen($b) ? 1 : -1;
  454. });
  455. return $codes[0] ?? null;
  456. }
  457. // endregion
  458. }