OrderPackageService.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <?php
  2. namespace App\Services;
  3. use App\OracleActAllocationDetails;
  4. use App\OracleDOCOrderDetail;
  5. use App\OracleDOCOrderHeader;
  6. use App\Order;
  7. use App\OrderPackage;
  8. use App\OrderPackageCommodities;
  9. use App\Services\common\BatchUpdateService;
  10. use Carbon\Carbon;
  11. class OrderPackageService
  12. {
  13. public function createdByOrder($order)
  14. {
  15. /** @var OrderPackageCommoditiesService $orderPackageCommoditiesService */
  16. $orderPackageCommoditiesService = app('orderPackageCommoditiesService');
  17. $oracleActAllocationDetails = OracleActAllocationDetails::query()->where('OrderNo', $order['code'])->get();
  18. $orderHeader = OracleDOCOrderHeader::query()->where('OrderNo', $order['code'])->first();
  19. $oracleDOCOrderDetail = OracleDOCOrderDetail::query()->where('OrderNo', $order['code'])->get();
  20. $logistic_number = null;
  21. if ($oracleActAllocationDetails->count() == 0) { // 通过oracle Order Detail
  22. $logistic_number = $orderHeader['soreference5'];
  23. if ($oracleDOCOrderDetail->count() == 0) {
  24. return null;
  25. }
  26. if ($logistic_number == null || $logistic_number == '*') {
  27. return null;
  28. }
  29. try {
  30. $orderPackage = OrderPackage::query()->firstOrCreate(['order_id' => $order['id'], 'logistic_number' => $logistic_number]);
  31. $orderPackageCommoditiesService->basedOnOracleDetailsStore($orderHeader['orderno'], $orderPackage);
  32. LogService::log(__METHOD__, __FUNCTION__, '创建订单包裹orderPackage' . json_encode($orderPackage));
  33. } catch (\Exception $e) {
  34. LogService::log(__METHOD__, __FUNCTION__, '创建订单包裹orderPackage失败' . $e->getMessage() . $e->getTraceAsString());
  35. }
  36. } else if ($oracleActAllocationDetails->count() > 0) {
  37. $count = $oracleActAllocationDetails->where('OrderNo', $order['code'])->whereNull('picktotraceid')->count();
  38. if ($count > 0) { // 快递单号为空
  39. if (($orderHeader['soreference5'] ?? false) && $orderHeader['soreference5'] == '*') {
  40. return null;
  41. }
  42. $logistic_number = $orderHeader['soreference5'];
  43. try {
  44. $orderPackage = OrderPackage::query()->firstOrCreate(['order_id' => $order['id'], 'logistic_number' => $logistic_number]);
  45. $orderPackageCommoditiesService->basedOnOracleDetailsStore($order, $orderPackage);
  46. LogService::log(__METHOD__, __FUNCTION__, '创建订单包裹orderPackage' . json_encode($orderPackage));
  47. } catch (\Exception $e) {
  48. LogService::log(__METHOD__, __FUNCTION__, '创建订单包裹orderPackage失败' . $e->getMessage() . $e->getTraceAsString());
  49. }
  50. } else {
  51. $ActAllocationDetails = $oracleActAllocationDetails->where('orderno', $order['code']);
  52. $picktotraceids = data_get($ActAllocationDetails,'*.picktotraceid');
  53. $picktotraceids = array_unique($picktotraceids);
  54. foreach ($picktotraceids as $picktotraceid) {
  55. $logistic_number = $picktotraceid;
  56. if ($logistic_number == null || $logistic_number == '*') {
  57. $logistic_number = $orderHeader['soreference5'];
  58. if ($logistic_number == null || $logistic_number == '*') {
  59. return null;
  60. }
  61. $orderPackage = OrderPackage::query()->where(['order_id' => $order['id'], 'logistic_number' => $logistic_number])->first();
  62. if ($orderPackage) {
  63. $orderPackageCommoditiesService->basedOnActAllocationDetailsStoreByOrderNo($order['code'], $orderPackage);
  64. continue;
  65. }
  66. try {
  67. $orderPackage = OrderPackage::query()->create(['order_id' => $order['id'], 'logistic_number' => $logistic_number]);
  68. $orderPackageCommoditiesService->basedOnActAllocationDetailsStoreByOrderNo($order['code'], $orderPackage);
  69. LogService::log(__METHOD__, __FUNCTION__, '创建订单orderPackage' . json_encode($orderPackage));
  70. } catch (\Exception $e) {
  71. LogService::log(__METHOD__, __FUNCTION__, '创建订单orderPackage失败' . json_encode($e->getMessage()) . json_encode($e->getTraceAsString()));
  72. }
  73. continue;
  74. }
  75. $orderPackage = OrderPackage::query()->where('order_id', $order['id'])->where('logistic_number', $logistic_number)->first();
  76. if ($orderPackage) {
  77. $orderPackageCommoditiesService->basedOnActAllocationDetailsStore($orderPackage);
  78. continue;
  79. }
  80. try {
  81. $orderPackage = OrderPackage::query()->create(['order_id' => $order['id'], 'logistic_number' => $logistic_number]);
  82. $orderPackageCommoditiesService->basedOnActAllocationDetailsStore($orderPackage);
  83. LogService::log(__METHOD__, __FUNCTION__, '创建订单' . json_encode($orderPackage));
  84. } catch (\Exception $e) {
  85. LogService::log(__METHOD__, __FUNCTION__, '创建订单orderPackage失败' . json_encode($e->getMessage()) . json_encode($e->getTraceAsString()));
  86. }
  87. }
  88. }
  89. }
  90. unset($oracleActAllocationDetails,$oracleDOCOrderDetail);
  91. }
  92. public function updateOrderPackageInfo(Order $order)
  93. {
  94. $orderHeader = OracleDOCOrderHeader::where('orderNo', $order['code'])->first();
  95. if ($orderHeader['oracleBASCode_codename_c'] == $order['wam_status']) {
  96. return;
  97. }
  98. $orderPackages = OrderPackage::where('order_id', $order['id'])->get();
  99. $orderPackageCommodities = OrderPackageCommodities::with('commodity')->whereIn('order_package_id', data_get($orderPackages, '*.id'))->get();
  100. $actAllocationDetails = OracleActAllocationDetails::where('orderNo', $order['client_code'])->get();
  101. if (count($orderPackageCommodities) < count($actAllocationDetails)) {
  102. $actAllocationDetails = $actAllocationDetails->reject(function ($value, $key) use (&$orderPackageCommodities) {
  103. $bool = false;
  104. $count = 0;
  105. $orderPackageCommodities->reject(function ($value1, $key1) use ($value, &$bool, $count) {
  106. if ($count > 0) {
  107. return false;
  108. }
  109. if ($value1->commodity['sku'] == $value['sku'] && $value1['amount'] == intval($value['qty'])) {
  110. $bool = true;
  111. $count++;
  112. return true;
  113. } else {
  114. return false;
  115. }
  116. });
  117. return $bool;
  118. });
  119. }
  120. $orderPackageCommoditiesService = app('orderPackageCommoditiesService');
  121. $orderPackageCommoditiesService->basedOnActAllocationDetail($order, $orderHeader, $actAllocationDetails);
  122. $order['wam_status'] = $orderHeader['oracleBASCode_codename_c'];
  123. $order->save();
  124. }
  125. /**
  126. * @param string $logistic_number
  127. * @param array $values
  128. * @return OrderPackage $package
  129. */
  130. public function firstOrCreate($logistic_number, array $values){
  131. /** @var $package OrderPackage */
  132. $package = OrderPackage::query()->where('logistic_number',$logistic_number)->first();
  133. if ($package)return $package;
  134. /** @var OrderService */
  135. $order = app('orderService')->logisticNumberCreateOrder($logistic_number);
  136. if ($order) $values["order_id"] = $order->id;
  137. $values["logistic_number"] = $logistic_number;
  138. /** @var OrderPackage $package */
  139. $package = OrderPackage::query()->create($values);
  140. return $package;
  141. }
  142. public function createExceptionPaginate($paginate)
  143. {
  144. return OrderPackage::query()->select('id', 'status', 'logistic_number', 'measuring_machine_id', 'weighed_at', 'weight', 'length', 'width', 'height', 'bulk', 'paper_box_id')
  145. ->where('status', '上传异常')->orWhere('status', '测量异常')->orderBy('created_at', 'DESC')
  146. ->paginate($paginate);
  147. }
  148. public function issueExceptionPaginate($paginate)
  149. {
  150. return OrderPackage::query()->select('id', 'logistic_number', 'created_at', 'batch_number', 'batch_rule')
  151. ->where('status', '下发异常')->orWhere('status', '记录异常')
  152. ->orWhere('status', '已上传异常')->orderBy('created_at', 'DESC')
  153. ->paginate($paginate);
  154. }
  155. public function 根据WMS订单创建WAS包裹($orderHeaders, $orders)
  156. {
  157. $orderPackagesFillables = [];
  158. foreach ($orders as $order) {
  159. $orderHeader = $orderHeaders[strval($order['code'])] ?? false;
  160. if(!$orderHeader){
  161. continue;
  162. }
  163. $fillables = $this->根据WMS订单生成包裹信息($orderHeader, $order);
  164. foreach ($fillables as $fillable) {
  165. $orderPackagesFillables[] = $fillable;
  166. }
  167. }
  168. try {
  169. if(count($orderPackagesFillables) > 0){
  170. OrderPackage::query()->insert($orderPackagesFillables);
  171. LogService::log(__METHOD__, __FUNCTION__, '批量订单包裹信息' .count($orderPackagesFillables). json_encode($orderPackagesFillables) );
  172. }
  173. } catch (\Exception $e) {
  174. LogService::log(__METHOD__, __FUNCTION__, '批量订单包裹信息 error' .json_encode($orderPackagesFillables) . $e->getMessage().$e->getTraceAsString());
  175. } finally {
  176. $order_ids = data_get($orders,'*.id');
  177. unset($orderPackagesFillables,$orders,$fillables);
  178. return Order::query()->with('packages')->whereIn('id',$order_ids)->get();
  179. }
  180. }
  181. public function 根据WMS订单生成包裹信息($orderHeader, $order)
  182. {
  183. $soReference5 = $orderHeader['soreference5'];
  184. $orderPackages= [];
  185. $logistic_numbers = [];
  186. foreach ($orderHeader['actAllocationDetails'] as $actAllocationDetail) {
  187. $logistic_numbers[] =$actAllocationDetail->picktotraceid;
  188. array_push($logistic_numbers,$actAllocationDetail['picktotraceid']);
  189. }
  190. $logistic_numbers = array_unique($logistic_numbers);
  191. $logistic_numbers = array_diff($logistic_numbers,['','*',null]);
  192. $logistic_numbers = count($logistic_numbers) == 0 ? ($soReference5 != '*' ? [$soReference5] : []) : $logistic_numbers;
  193. $logistic_numbers = array_diff($logistic_numbers,['','*',null]);
  194. if(count($logistic_numbers) == 0 ){ return [];}
  195. if (count($logistic_numbers) != 0) {
  196. foreach ($logistic_numbers as $logistic_number) {
  197. $fillable = [
  198. 'order_id' => $order['id'],
  199. 'logistic_number' => $logistic_number,
  200. ];
  201. $orderPackages[] = $fillable;
  202. }
  203. }
  204. return $orderPackages;
  205. }
  206. public function 更新WAS订单的包裹的重量和体积($orderHeaders,$orderPackages)
  207. {
  208. /** @var CommodityService $commodityService */
  209. $commodityService = app('commodityService');
  210. $commodities = $commodityService->getWASCommoditiesByWMSOrderHeaders($orderHeaders); // 商品
  211. $multipleData = [['id','weight','bulk']];
  212. $noAttributeCommodity = [];
  213. $commodity_map = [];
  214. foreach ($commodities as $commodity) {
  215. $key = ' id='.$commodity->id;
  216. $commodity_map[$key] = $commodity;
  217. }
  218. foreach ($orderPackages as $packages) {
  219. foreach ($packages as $package) {
  220. if($package == null){
  221. continue;
  222. }
  223. $orderPackageCommodities = $package['commodities'] ?? [];
  224. $updateArr = [
  225. 'id' => $package['id'],
  226. 'weight' => 0,
  227. 'bulk' => 0,
  228. ];
  229. foreach ($orderPackageCommodities as $packageCommodity) {
  230. $commodity = $commodity_map[' id='.$packageCommodity->commodity_id];
  231. if($commodity['weight'] == 0 || !$commodity['bulk'] == 0 ){
  232. array_push($noAttributeCommodity,$commodity);
  233. }
  234. $updateArr['weight'] += bcmul($commodity['weight'], $packageCommodity['amount'],5);
  235. $updateArr['bulk'] += bcmul($commodity['bulk'], $packageCommodity['amount'],5);
  236. //$updateArr['weight'] +=(intval($commodity['weight'] ?? 0) ) * ( intval($packageCommodity['amount'] ?? 0) );
  237. //$updateArr['bulk'] += (intval($commodity['bulk'] ?? 0)) * (intval($packageCommodity['amount'] ?? 0) );
  238. }
  239. if($package['weight'] == $updateArr['weight'] && $package['bulk'] == $updateArr['bulk']){
  240. continue;
  241. }
  242. // 订单同步步时 重量 体积不覆盖已有值
  243. if($packages['weight'] ?? false){
  244. $updateArr['weight'] = $packages['weight'];
  245. }
  246. if($packages['bulk'] ?? false){
  247. $updateArr['bulk'] = $packages['bulk'];
  248. }
  249. $multipleData[] = $updateArr;
  250. }
  251. }
  252. if(count($multipleData) > 1){
  253. /** @var BatchUpdateService $batchUpdateService */
  254. $batchUpdateService = app('batchUpdateService');
  255. $batchUpdateService->batchUpdate('order_packages',$multipleData);
  256. }
  257. array_unique($noAttributeCommodity);
  258. if(count($noAttributeCommodity) > 1){
  259. $commodityService->syncCommodityAttribute($noAttributeCommodity);
  260. }
  261. unset($multipleData,$noAttributeCommodity,$commodities);
  262. }
  263. public function 更新WAS订单快递单号信息($orderHeaders,$orders)
  264. {
  265. $fillables = [];
  266. $orders_map = [];
  267. $orders_package_map = [];
  268. foreach ($orders as $order){
  269. $key = $order['code'];
  270. $orders_map[$key] = $order;
  271. foreach ($order['packages'] as $package) {
  272. $logistic_numbers = $package['logistic_number'];
  273. $orders_package_map[$key][$logistic_numbers] =$package;
  274. }
  275. }
  276. foreach ($orderHeaders as $key=>$orderHeader) {
  277. $order = $orders[$key] ?? false;
  278. if(!$order){
  279. continue;
  280. }
  281. $packages = $orders_package_map[$key] ?? false;
  282. $pickToTraceIds = [];
  283. foreach ($orderHeader->actAllocationDetails as $actAllocationDetail) {
  284. $pickToTraceIds[] = $actAllocationDetail['picktotraceid'];
  285. }
  286. $pickToTraceIds = array_unique(array_diff($pickToTraceIds,['','*',null]));
  287. foreach ($pickToTraceIds as $pickToTraceId) {
  288. if(!$packages || !($orders_package_map[$key][$pickToTraceId] ?? false)){
  289. $fillables[] = [
  290. 'order_id' => $order->id,
  291. 'logistic_number' => $pickToTraceId
  292. ];
  293. }
  294. }
  295. }
  296. try {
  297. if(count($fillables)>0){
  298. OrderPackage::query()->insert($fillables);
  299. LogService::log(__METHOD__,__FUNCTION__,'创建orderPackage:'.json_encode($fillables));
  300. }
  301. } catch (\Exception $e) {
  302. LogService::log(__METHOD__,__FUNCTION__,'创建orderPackage 失败:'.json_encode($fillables).$e->getMessage().$e->getTraceAsString());
  303. } finally {
  304. unset($fillables);
  305. }
  306. }
  307. }