RejectedBillSyncOrderService.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. namespace App\Services;
  3. use App\Commodity;
  4. use App\CommodityBarcode;
  5. use App\OracleDOCOrderHeader;
  6. use App\Order;
  7. use App\OrderIssue;
  8. use App\OrderIssueRejectedBill;
  9. use App\OrderPackage;
  10. use App\RejectedBill;
  11. use App\RejectedBillItem;
  12. use App\WorkOrder;
  13. class RejectedBillSyncOrderService
  14. {
  15. public function syncRejectingStatusByReturnLogisticNumber($returnLogisticNumber){
  16. /** @var RejectedBill $rejected_bill */
  17. $rejected_bill = RejectedBill::query()->where('logistic_number_return',$returnLogisticNumber)->first();
  18. if(!$rejected_bill) return;
  19. $this->rejectedBillSyncOrderIssue($rejected_bill);
  20. $this->syncRejectingStatus($rejected_bill);
  21. }
  22. public function syncRejectingStatus(RejectedBill $rejectedBill)
  23. {
  24. /** @var Order $order */
  25. $order = $this->getCorrespondOrder($rejectedBill);
  26. if(!$order) return;
  27. $rejecting_status = $this->getOrderRejectingStatus($order);
  28. $this->syncOrderRejectingStatus($order,$rejecting_status);
  29. }
  30. private function syncOrderRejectingStatus(Order $order,$rejecting_status){
  31. OrderIssue::query()->where('order_id',$order->id)->update(['rejecting_status' => $rejecting_status,'is_new_rejecting' => 1]);
  32. WorkOrder::query()->where('order_id',$order->id)->update(['rejecting_status' => $rejecting_status,'is_new_rejecting' => 1]);
  33. }
  34. public function orderIssueSyncRejectingStatus(OrderIssue $orderIssue){
  35. $order = $orderIssue->order;
  36. if (!$order) return;
  37. $this->orderIssueSyncRejectedBills($orderIssue);
  38. $rejecting_status = $this->getOrderRejectingStatus($order);
  39. $this->syncOrderRejectingStatus($order,$rejecting_status);
  40. }
  41. public function getOrderRejectingStatus(Order $order): string
  42. {
  43. $rejected_bill_items = $this->getRejectedBillItems($order);
  44. $rejected_bill_item_map = $this->getRejectedBillMaps($rejected_bill_items,$order);
  45. $order_commodity_map = $this->getOrderCommodityMap($order);
  46. return $this->computerRejectingStatus($rejected_bill_item_map,$order_commodity_map);
  47. }
  48. private function getCorrespondOrder(RejectedBill $rejectedBill)
  49. {
  50. return $this->getCorrespondOrderByRejectedBill($rejectedBill) ??
  51. ($this->getCorrespondOrderByOrderIssueRejectedBill($rejectedBill) ??
  52. $this->getCorrespondOrderByOracleOrderHeader($rejectedBill));
  53. }
  54. private function getCorrespondOrderByRejectedBill(RejectedBill $rejectedBill)
  55. {
  56. return Order::query()->with('packages.commodities.commodity')->whereHas('packages', function ($query) use ($rejectedBill) {
  57. $query->where('logistic_number', $rejectedBill->logistic_number_return);
  58. })->first();
  59. }
  60. private function getCorrespondOrderByOrderIssueRejectedBill(RejectedBill $rejectedBill)
  61. {
  62. if (!$rejectedBill) return null;
  63. $order_issue_rejected_bill_query = OrderIssueRejectedBill::query()
  64. ->select('order_issue_id')->where('logistic_number_return',$rejectedBill->logistic_number_return);
  65. $order_issue_query = OrderIssue::query()
  66. ->select('order_id')->whereIn('order_issue_id',$order_issue_rejected_bill_query);
  67. return Order::query()->with('packages.commodities.commodity')->whereIn('id', $order_issue_query)->first();
  68. }
  69. private function getCorrespondOrderByOracleOrderHeader(RejectedBill $rejectedBill)
  70. {
  71. if (!$rejectedBill) return null;
  72. $orderHeader = OracleDOCOrderHeader::query()->selectRaw('OrderNO')->where('SoReference1', function ($query) use ($rejectedBill) {
  73. $query->select('AsnReference2')->from('DOC_ASN_HEADER')->where('AsnReference3', $rejectedBill->logistic_number_return)->first();
  74. })->first();
  75. if (!$orderHeader) return null;
  76. return Order::query()->with('packages.commodities.commodity')->where('code', $orderHeader->orderno)->first();
  77. }
  78. private function getRejectedBillItems(Order $order)
  79. {
  80. $query = OrderIssue::query()->select('id')->where('order_id',$order->id);
  81. $query = OrderIssueRejectedBill::query()->select('logistic_number_return')->whereIn('order_issue_id',$query);
  82. $query = RejectedBill::query()->select('id')->whereIn('logistic_number_return',$query);
  83. return RejectedBillItem::query()->with('quality')->whereIn('id_rejected_bill',$query)->get();
  84. }
  85. private function getRejectedBillMaps($rejectedBillItems,$order): array
  86. {
  87. $map = [];
  88. if(!$rejectedBillItems) return $map;
  89. foreach ($rejectedBillItems as $item) {
  90. $code = $item->barcode_goods;
  91. $amount = $item->amount;
  92. if (!Commodity::query()->where("sku", $code)->where('owner_id',$order->owner_id)->exists()) {
  93. $query = CommodityBarcode::query()->select('commodity_id')->where('code',$code);
  94. $commodity = Commodity::query()->where('owner_id',$order->owner_id)->whereIn('id',$query)->first();
  95. if ($commodity)$code = $commodity->sku;
  96. }
  97. $quality_name = $item->quality->name;
  98. if($map[$code][$quality_name] ?? false) $map[$code][$quality_name] += $amount;
  99. else $map[$code][$quality_name] = $amount;
  100. }
  101. return $map;
  102. }
  103. private function getOrderCommodityMap(Order $order): array
  104. {
  105. $map = [];
  106. $order->packages->each(function ($package)use($order,&$map){
  107. $package->commodities->map(function($item) use($order,&$map){
  108. $sku = $item->commodity->sku ?? null;
  109. if ($sku) {
  110. $amount = $item->amount;
  111. empty($map[$sku]) ? $map[$sku] = $amount : $map[$sku]+=$amount ;
  112. }
  113. });
  114. });
  115. return $map;
  116. }
  117. private function computerRejectingStatus(array $rejected_bill_item_map, array $order_commodity_map):string
  118. {
  119. //未退回,差异退回,全部退回,超量退回,部分退回
  120. if (count($rejected_bill_item_map) == 0) return "未退回";
  121. $equal = 0; // 相等sku
  122. $portion = 0; // 相等的sku
  123. foreach ($rejected_bill_item_map as $key => $map) {
  124. if (isset($map['残次']) && $map['残次'] > 0) return "差异退回";
  125. if (empty($order_commodity_map[$key])) return "差异退回";
  126. if(isset($map['正品']) && isset($order_commodity_map[$key])){
  127. if ( $map['正品'] < $order_commodity_map[$key]) $portion += 1;
  128. if ( $map['正品'] > $order_commodity_map[$key]) return "超量退回";
  129. if ( $map['正品'] == $order_commodity_map[$key]) $equal += 1;
  130. }
  131. }
  132. if ($equal == count($rejected_bill_item_map)
  133. && $equal == count($rejected_bill_item_map)
  134. && $portion == 0) return "全部退回"; // 全部退回
  135. if ($portion > 0) return "部分退回";
  136. if (count(array_diff_key($rejected_bill_item_map,$order_commodity_map)) > 0)return '部分退回';
  137. if (count(array_diff_key($order_commodity_map,$rejected_bill_item_map)) > 0)return '差异退回';
  138. return "无";
  139. }
  140. public function orderIssueSyncRejectedBills(OrderIssue $orderIssue)
  141. {
  142. $logistic_numbers = OrderPackage::query()->where('order_id',$orderIssue->order_id)->get()->map(function($item){
  143. return $item->logistic_number;
  144. })->toArray();
  145. $rejected_bills = RejectedBill::query()->select('logistic_number_return')
  146. ->whereIn('logistic_number_return',$logistic_numbers)
  147. ->get()->map(function($item){
  148. return $item->logistic_number_return;
  149. })->toArray();
  150. if(count($rejected_bills) === 0) return;
  151. $order_issue_rejected_bills = OrderIssueRejectedBill::query()->where('order_issue_id',$orderIssue->id)->get()->map(function ($item){
  152. return $item->logistic_number_return;
  153. })->toArray();
  154. $insert_param = array_map(function($item)use($orderIssue){
  155. return ['order_issue_id' => $orderIssue->id,'logistic_number_return' => $item];
  156. },array_diff($rejected_bills,$order_issue_rejected_bills));
  157. OrderIssueRejectedBill::query()->insert($insert_param);
  158. }
  159. public function rejectedBillSyncOrderIssue(RejectedBill $rejectedBill){
  160. $reaction_exists = OrderIssueRejectedBill::query()->where('logistic_number_return',$rejectedBill->logistic_number_return)->exists();
  161. if ($reaction_exists) return;
  162. $query = Order::query()->select('id')->whereHas('packages',function($query)use($rejectedBill){
  163. $query->where('logistic_number',$rejectedBill->logistic_number_return);
  164. });
  165. $order_issue = OrderIssue::query()->whereIn('order_id',$query)->first();
  166. OrderIssueRejectedBill::query()->create(['order_issue_id' => $order_issue->id,'logistic_number_return' => $rejectedBill->logistic_number_return]);
  167. }
  168. }