You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
7.8 KiB

  1. <?php
  2. namespace backend\modules\shop\logic\delivery;
  3. use backend\modules\shop\models\ars\Delivery;
  4. use backend\modules\shop\models\ars\DeliveryGoods;
  5. use backend\modules\shop\models\ars\ExpressTemplate;
  6. use backend\modules\shop\models\ars\Order;
  7. use backend\modules\shop\models\ars\OrderGoods;
  8. use Yii;
  9. use yii\db\Exception;
  10. use yii\helpers\ArrayHelper;
  11. class DeliveryManager
  12. {
  13. /**
  14. * @param $order
  15. * @param $delivery
  16. * @return array
  17. * 订单发货
  18. */
  19. public static function orderDelivery($order, $delivery)
  20. {
  21. $transaction = Yii::$app->db->beginTransaction();
  22. try {
  23. $data = Yii::$app->request->post();
  24. if (empty($data['deliveryGoods'])) {
  25. throw new Exception('缺少发货商品信息');
  26. }
  27. $delivery->load($data);
  28. $delivery->order_id = $order->id;
  29. if (!$delivery->save()) {
  30. throw new Exception('保存物流信息失败');
  31. }
  32. /*发货商品数据*/
  33. $orderStatus = self::saveDeliveryGoods($data['deliveryGoods'], $delivery->id);
  34. $order->status = $orderStatus;
  35. if (!$order->save()) {
  36. throw new Exception('order shipping_status update false');
  37. }
  38. if ($orderStatus == Order::STATUS_SHIPMENT_PORTION || Delivery::findOne(['!=', 'id', $delivery->id])) {
  39. $delivery->type = Delivery::TYPE_SHIPMENT_PORTION;
  40. } else {
  41. $delivery->type = Delivery::TYPE_SHIPMENT_ALL;
  42. }
  43. if (!$delivery->save()) {
  44. throw new Exception('保存物流信息失败');
  45. }
  46. $transaction->commit();
  47. return ['status' => true];
  48. } catch (Exception $e) {
  49. $transaction->rollBack();
  50. return ['status' => false, 'info' => $e->getMessage()];
  51. }
  52. }
  53. /**
  54. * @param $deliveryGoods
  55. * @param $delivery_id
  56. * @return int
  57. * @throws Exception
  58. * 保存发货商品信息
  59. */
  60. private static function saveDeliveryGoods($deliveryGoods, $delivery_id)
  61. {
  62. $status = Order::STATUS_SHIPMENT_ALL;
  63. foreach ($deliveryGoods as $id => $goodsCount) {
  64. if ($goodsCount < 0) {
  65. throw new Exception('操作异常,发货数量不能小于0');
  66. } elseif ($goodsCount == 0) {
  67. continue;
  68. }
  69. $orderGoods = OrderGoods::findOne($id);
  70. /*如果是发货数量不是全部,订单状态为部分发货*/
  71. $deliveryGoodsCount = DeliveryGoods::find()->where(['order_goods_id' => $id])->sum('goods_count');
  72. if (($deliveryGoodsCount + $goodsCount) < $orderGoods->goods_count) { //如果已发货数量未达到order_goods里的数量
  73. $status = Order::STATUS_SHIPMENT_PORTION;
  74. } elseif (($deliveryGoodsCount + $goodsCount) > $orderGoods->goods_count) {
  75. throw new Exception('操作异常,现发货数量超过之前缺少的发货数量');
  76. }
  77. $model = new DeliveryGoods();
  78. $model->delivery_id = $delivery_id;
  79. $model->order_goods_id = $orderGoods->id;
  80. $model->goods_id = $orderGoods->goods_id;
  81. $model->goods_name = $orderGoods->goods_name;
  82. $model->goods_count = $goodsCount;
  83. if (!$model->save()) {
  84. throw new Exception('delivery_goods save false');
  85. }
  86. }
  87. return $status;
  88. }
  89. /**
  90. * @param $order_id
  91. * @return array
  92. * @throws Exception
  93. * 获取发货全部商品信息
  94. */
  95. public static function deliveryGoodsInfo($order_id)
  96. {
  97. $delivery = Delivery::find()->select('id')->where(['order_id' => $order_id])->all();
  98. /*如果该订单是首次发货*/
  99. if (!$delivery) {
  100. $unShippedGoods = OrderGoods::find()->where(['order_id' => $order_id])->asArray()->all();
  101. return ['unShipped' => $unShippedGoods];
  102. }
  103. $filter = [];
  104. $deliveryIds = [];
  105. foreach ($delivery as $value) {
  106. $deliveryIds[] = $value->id;
  107. }
  108. $deliveryGoods = DeliveryGoods::find()->where(['delivery_id' => $deliveryIds])->all();
  109. for ($i = 0; $i < count($deliveryGoods); $i++) {
  110. $orderGoodsId = $deliveryGoods[$i]['order_goods_id'];
  111. //以orderGoods的id为键名,以orderGoods的数量为键值,先保存到filter数组中
  112. $filter[$orderGoodsId] = $deliveryGoods[$i]['goods_count'];
  113. for ($j = 0; $j < count($deliveryGoods); $j++) {
  114. //如果发货商品中有其他相同orderGoods的商品
  115. if ($orderGoodsId == $deliveryGoods[$j]['order_goods_id'] && $i != $j) {
  116. //商品数量叠加起来并保存
  117. $filter[$orderGoodsId] += $deliveryGoods[$j]['goods_count'];
  118. }
  119. }
  120. }
  121. /*获取订单已发的商品和未发的商品*/
  122. return self::getDeliveryGoodsInfo($filter, $order_id);
  123. }
  124. /**
  125. * @param $filter
  126. * @param $order_id
  127. * @return array
  128. * @throws Exception
  129. * 获取订单已发的商品和未发的商品
  130. */
  131. public static function getDeliveryGoodsInfo($filter, $order_id)
  132. {
  133. $unShipped = []; //未发货商品
  134. foreach ($filter as $k => $value) { //键名为order_goods_id,键值为对应的已发货数量
  135. $goodsData = self::getOrderGoodsInfo($k);
  136. if ($value < $goodsData['goods_count']) { //如果已发货数量未达到order_goods里的数量
  137. $lack_number = $goodsData['goods_count'] - $value;
  138. $goodsData['lack_number'] = $lack_number;
  139. $goodsData['goods_count'] = $lack_number;
  140. $unShipped[] = $goodsData;
  141. }
  142. }
  143. $shipped = [];
  144. $delivery = Delivery::findAll(['order_id' => $order_id]);
  145. foreach ($delivery as $k => $value) {
  146. $shipped[$k]['logisticInfo'] = [
  147. 'exp_name' => '',
  148. 'invoice_no' => '',
  149. 'created_at' => '',
  150. ]; //物流公司和运单号
  151. $shipped[$k]['goodsInfo'] = self::getDeliverGoodsInfo($value->id); //获取商品信息
  152. }
  153. return ['shipped' => $shipped, 'unShipped' => $unShipped];
  154. }
  155. /**
  156. * @param $delivery_id
  157. * @return array
  158. * @throws Exception
  159. * 通过获取订单已发货的商品信息
  160. */
  161. public static function getDeliverGoodsInfo($delivery_id)
  162. {
  163. $goodsInfo = [];
  164. $deliveryGoods = DeliveryGoods::find()
  165. ->where(['delivery_id' => $delivery_id])
  166. ->andWhere(['>', 'goods_count', 0])
  167. ->all();
  168. foreach ($deliveryGoods as $value) {
  169. $goodsData = self::getOrderGoodsInfo($value->order_goods_id);
  170. $goodsData['delivery_number'] = $value->goods_count;
  171. $goodsInfo[] = $goodsData;
  172. }
  173. return $goodsInfo;
  174. }
  175. /**
  176. * @param $order_goods_id
  177. * @return array
  178. * @throws Exception
  179. * 获取订单商品信息
  180. */
  181. private static function getOrderGoodsInfo($order_goods_id)
  182. {
  183. $orderGoods = OrderGoods::findOne($order_goods_id); //通过orderGoods_id找到订单商品
  184. if ($orderGoods) {
  185. $goodsData = [
  186. 'id' => $orderGoods->id,
  187. 'goods_id' => $orderGoods->goods_id,
  188. 'goods_name' => $orderGoods->goods_name,
  189. 'goods_count' => $orderGoods->goods_count,
  190. 'goods_img' => $orderGoods->goods_img,
  191. 'sku_value' => $orderGoods->sku_value,
  192. ];
  193. return $goodsData;
  194. } else {
  195. throw new Exception('order_goods not found');
  196. }
  197. }
  198. }