LogisticSyncTrait.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace App\Traits;
  3. use App\OrderPackage;
  4. use Illuminate\Support\Carbon;
  5. use Illuminate\Support\Str;
  6. use function DeepCopy\deep_copy;
  7. trait LogisticSyncTrait
  8. {
  9. public function setExceptionStatus(array $data): array
  10. {
  11. $logistic_number = $data['logistic_number'];
  12. /** @var OrderPackage $orderPackage */
  13. $orderPackage = OrderPackage::query()
  14. ->with(['order'])
  15. ->where('logistic_number', $logistic_number)
  16. ->first();
  17. if ($orderPackage->exception_status === '单号异常' ||
  18. $orderPackage->exception_status === '无法获取路由') {//这种类型的单,不需要再更新状态
  19. return $data;
  20. }
  21. /** @var \Carbon\Carbon $sent_at */
  22. $sent_at = $orderPackage->sent_at;
  23. /**执行该方法时,默认没有异常,
  24. *1. 之前有异常的件,
  25. * 1.1 新的状态是无异常的可以更新为正常
  26. * 1.2 新的状态是异常的可以更新为对应异常
  27. *2. 之前无异常
  28. * 2.1 新的状态无异常更新为无异常
  29. * 2.2 新的状态异常更新为对应异常
  30. */
  31. $data['exception_status'] = '';
  32. $created_at = Carbon::parse($orderPackage->created_at);
  33. //当天的16:30
  34. $transfer_status = $data['transfer_status'] ?? [];
  35. if (empty($sent_at)) {//没复核
  36. if (empty($transfer_status)) {//没有路由信息
  37. //延迟发货
  38. $created_at_clone = deep_copy($created_at);
  39. if ($created_at->gt($created_at_clone->startOfDay()->addHours(16)->addMinutes(30))) {//下午16的单
  40. $created_at_clone = deep_copy($created_at);
  41. if ($created_at_clone->addDay()->endOfDay()->lt(now())) {//超过第二天的24时
  42. $created_at_clone = deep_copy($created_at);
  43. $data['exception_status'] = '延迟发货';
  44. $data['is_delay_deliver'] = true;
  45. }
  46. } else {
  47. if ($created_at_clone->endOfDay()->lt(now())) {//超过当天的24时
  48. $data['exception_status'] = '延迟发货';
  49. $data['is_delay_deliver'] = true;
  50. }
  51. }
  52. } else {
  53. //虚拟揽件
  54. // $data['exception_status'] = '虚拟揽件'; //没有复核但是有路由信息 21-09-10 取消虚拟揽件状态
  55. }
  56. } else {//复核过
  57. if (empty($transfer_status)) {//没有路由信息
  58. /** @var Carbon $temp_time */
  59. $temp_time = $orderPackage->weighed_at ?: $orderPackage->sent_at;//揽收异常以称重时间优先 没有称重以发出时间
  60. if (now()->gt($temp_time->addDay()->startOfDay()->addHours(6))) {//当前时间大于复核时间的第二天6点
  61. if (empty($orderPackage->weighed_at)) {//没有称重
  62. $data['exception_status'] = '疑似库内丢件';
  63. } else {//有称重
  64. $data['exception_status'] = '揽件异常';
  65. }
  66. }
  67. } else {//有路由信息
  68. $transfer_status = $this->sortTransferStatusByAcceptTimeDESC($transfer_status);
  69. $last_transfer_accept_time = $transfer_status[0]['accept_time'];
  70. $last_remark = empty(!$transfer_status[0]['remark']) ? $transfer_status[0]['remark'] : $transfer_status[0]['accept_address'];
  71. if (count($transfer_status) < 3) {//三条以内的不管地区 时间限制为24h
  72. if (Carbon::parse($last_transfer_accept_time)->diffInHours(now()) > 24) {
  73. $data['exception_status'] = '在途异常';
  74. }
  75. } else {
  76. $SHORT_RESPONSE_HOURS = (function ($province) {
  77. switch ($province) {
  78. case '浙江省':
  79. case '江苏省':
  80. case '上海':
  81. case '安徽省':
  82. return 24;
  83. case '北京':
  84. case '天津':
  85. case '江西省':
  86. case '湖北省':
  87. case '湖南省':
  88. case '广东省':
  89. case '福建省':
  90. case '山东省':
  91. case '河北省':
  92. case '河南省':
  93. case '山西省':
  94. case '四川省':
  95. case '陕西省':
  96. case '重庆':
  97. case '广西壮族自治区':
  98. case '贵州省':
  99. case '云南省':
  100. case '海南省':
  101. case '吉林省':
  102. case '黑龙江省':
  103. case '辽宁省':
  104. return 72;
  105. case '青海省':
  106. case '宁夏回族自治区':
  107. case '甘肃省':
  108. case '内蒙古自治区':
  109. case '新疆维吾尔自治区':
  110. case '西藏自治区':
  111. return 120;
  112. default:
  113. return 24;
  114. }
  115. })($orderPackage->order->province);
  116. if (Carbon::parse($last_transfer_accept_time)->diffInHours(now()) > $SHORT_RESPONSE_HOURS) {
  117. $data['exception_status'] = '在途异常';
  118. }
  119. }
  120. if (($data['exception_status'] ?? '' === '在途异常') && ($data['status'] ?? '' === '派送中')) {//在途异常修正为派送异常
  121. $data['exception_status'] = '派送异常';
  122. }
  123. if (Str::contains($last_remark, ['代收', '快递柜', '驿站', '自提柜', '丰巢', '快递小屋', '合作点', '快递超市', '签收'])) {
  124. $data['exception_status'] = '';
  125. $data['status'] = '已签收';
  126. }
  127. }
  128. }
  129. //如果复核时间>前一天的18.00,则不添加异常信息
  130. if ((!empty($sent_at)) && ($sent_at->gt(now()->subDay()->startOfDay()->addHours(18))) && isset($data['exception_status'])) {
  131. unset($data['exception_status']);
  132. }
  133. //邮政待揽收状态不是在途
  134. $logistic_id = $orderPackage->order->logistic_id ?? null;
  135. if ((!empty($logistic_id)) && ($logistic_id === 6 || $logistic_id === 88)) {
  136. if (!empty($transfer_status)) {
  137. $this->sortTransferStatusByAcceptTimeDESC($transfer_status);
  138. $last_remark = empty(!$transfer_status[0]['remark']) ? $transfer_status[0]['remark'] : $transfer_status[0]['accept_address'];
  139. if (Str::contains($last_remark, ['等待揽收', '商品已下单'])) {
  140. $data['status'] = '已复核';
  141. }
  142. }
  143. }
  144. return $data;
  145. }
  146. /**
  147. * @param $transfer_status
  148. * @return mixed
  149. */
  150. private function sortTransferStatusByAcceptTimeDESC($transfer_status)
  151. {
  152. usort($transfer_status, function ($a, $b) {
  153. if ($a['accept_time'] === $b['accept_time']) {
  154. return 0;
  155. }
  156. return ($a['accept_time'] > $b['accept_time']) ? -1 : 1;
  157. });
  158. return $transfer_status;
  159. }
  160. }