OrderRefundForm.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\client\models\v1;
  8. use app\models\common\events\OrderEvent;
  9. use app\models\Order;
  10. use app\models\OrderDetail;
  11. use app\models\OrderGoodsCancel;
  12. use app\models\OrderRefund;
  13. use app\modules\admin\models\MerchantForm;
  14. use app\modules\client\models\OrderComplete;
  15. use yii\base\BaseObject;
  16. use yii\base\Model;
  17. use yii\helpers\Html;
  18. use yii\helpers\Json;
  19. class OrderRefundForm extends Model
  20. {
  21. public $store_id;
  22. public $user_id;
  23. public $order_detail_id;
  24. public $type;
  25. public $desc;
  26. public $pic_list;
  27. public $form_id;
  28. public $stbz_apply_data;
  29. public function rules()
  30. {
  31. return [
  32. [['form_id'], 'default', 'value' => ''],
  33. [['desc'], 'trim'],
  34. [['type', 'desc', 'order_detail_id'], 'required'],
  35. [['type',], 'in', 'range' => [1, 2]],
  36. [['pic_list',], 'string'],
  37. [['stbz_apply_data',], 'safe'],
  38. ];
  39. }
  40. public function save()
  41. {
  42. if (!$this->validate()) {
  43. return [
  44. 'code' => 1,
  45. 'msg' => $this->getErrorSummary(false)[0],
  46. ];
  47. }
  48. $order_detail_id = Json::decode(post_params('order_detail_id'));
  49. if (!$order_detail_id) {
  50. return [
  51. 'code' => 1,
  52. 'msg' => '参数错误',
  53. ];
  54. }
  55. $order_detail = OrderDetail::findOne([
  56. 'id' => $order_detail_id[0],
  57. 'is_delete' => 0,
  58. ]);
  59. $order = Order::findOne([
  60. 'id' => $order_detail->order_id,
  61. 'is_delete' => 0,
  62. ]);
  63. $order_detail_info = OrderDetail::find()
  64. ->where(['id' => $order_detail_id])
  65. ->select('id, num')->asArray()->all();
  66. $order_detail_id = [];
  67. foreach ($order_detail_info as $order_detail_item) {
  68. $cancel_num = OrderGoodsCancel::find()->where(['order_detail_id' => $order_detail_item['id'], 'status' => [
  69. OrderGoodsCancel::STATUS_PASS,
  70. OrderGoodsCancel::STATUS_PAY,
  71. OrderGoodsCancel::STATUS_PAY_FAIL
  72. ]])->sum('num');
  73. if ($cancel_num < $order_detail_item['num']) {
  74. $order_detail_id[] = $order_detail_item['id'];
  75. }
  76. }
  77. $refund_price = 0;
  78. if (is_array($order_detail_id) && !empty($order_detail_id)) {
  79. foreach ($order_detail_id as $detail_id) {
  80. $order_detail = OrderDetail::findOne([
  81. 'id' => $detail_id,
  82. 'is_delete' => 0,
  83. ]);
  84. if (!$order_detail) {
  85. return [
  86. 'code' => 1,
  87. 'msg' => '订单商品不存在,无法申请售后',
  88. ];
  89. }
  90. $orderGoodsCancel = OrderGoodsCancel::find()->where([
  91. 'order_id' => $order_detail->order_id,
  92. 'order_detail_id' => $detail_id,
  93. 'status' => [
  94. OrderGoodsCancel::STATUS_PASS,
  95. OrderGoodsCancel::STATUS_PAY,
  96. OrderGoodsCancel::STATUS_PAY_FAIL
  97. ]
  98. ])->groupBy('order_detail_id')->select('SUM(num) as num, SUM(refund_price) as refund_price')
  99. ->asArray()->one();
  100. if ($orderGoodsCancel) {
  101. $order_detail->total_price = bcsub($order_detail->total_price, $orderGoodsCancel['refund_price'], 2);
  102. $order_detail->num = bcsub($order_detail->num, $orderGoodsCancel['num']);
  103. }
  104. $order = Order::findOne([
  105. // 秒杀订单没有详情
  106. 'id' => $order_detail->order_id,
  107. 'is_delete' => 0,
  108. ]);
  109. $notAllow = !in_array($this->user_id, [$order->user_id, $order->giving_gifts_received_user_id]);
  110. if (!$order || $notAllow) {
  111. return [
  112. 'code' => 1,
  113. 'msg' => '订单不存在,无法申请售后',
  114. ];
  115. }
  116. if (intval($order->is_sale) !== 0) {
  117. return [
  118. 'code' => 1,
  119. 'msg' => '订单已经过售后期,无法申请售后',
  120. ];
  121. }
  122. if ($order->is_pay != 1) {
  123. return [
  124. 'code' => 1,
  125. 'msg' => '订单尚未支付,无法申请售后',
  126. ];
  127. }
  128. if($order->share_hold_pay_up == 1){
  129. return [
  130. 'code' => 1,
  131. 'msg' => '股东升级订单不能退换货',
  132. ];
  133. }
  134. $refund_price = bcadd($refund_price, $order_detail->total_price, 2);
  135. //计算立减
  136. $orderDetail = OrderDetail::find()->where(['order_id' => $order->id, 'is_delete' => 0])->asArray()->all();
  137. $num = array_sum(array_column($orderDetail, 'num'));
  138. $rand_discount = sprintf('%.2f', (($order->rand_discount ?: 0) * (($order_detail->num ?: 1) / ($num ?: 1))));
  139. $refund_price -= $rand_discount;
  140. }
  141. }
  142. if ($refund_price <= 0) {
  143. return [
  144. 'code' => 1,
  145. 'msg' => '退款金额错误',
  146. ];
  147. }
  148. $queryOrderRefund = OrderRefund::find();
  149. $queryOrderRefund->where([
  150. 'store_id' => $this->store_id,
  151. 'user_id' => $this->user_id,
  152. 'is_delete' => 0,
  153. ]);
  154. $existRefund = $queryOrderRefund->andWhere(['order_detail_id' => json_encode($order_detail_id, JSON_UNESCAPED_UNICODE)])->one();
  155. if ($existRefund) {
  156. return [
  157. 'code' => 1,
  158. 'msg' => '该商品已申请过售后,请不要重复申请',
  159. ];
  160. }
  161. $refund = new OrderRefund();
  162. $refund->store_id = $this->store_id;
  163. $refund->user_id = $this->user_id;
  164. $refund->order_id = $order->id;
  165. $refund->order_detail_id = Json::encode($order_detail_id);
  166. $refund->type = $this->type;
  167. $refund->order_refund_no = $this->getOrderRefundNo();
  168. if ($order->md_id) {
  169. $refund->md_id = $order->md_id;
  170. }
  171. if ($refund->type == 1) {
  172. $refund->refund_price = $refund_price;
  173. } elseif ($refund->type == 2) {
  174. $refund->refund_price = 0;
  175. } else {
  176. return [
  177. 'code' => 1,
  178. 'msg' => '未知售后类型'
  179. ];
  180. }
  181. $refund->desc = $this->desc;
  182. $this->pic_list = json_decode($this->pic_list);
  183. $pic_list = [];
  184. if (is_array($this->pic_list)) {
  185. foreach ($this->pic_list as $item) {
  186. if (is_string($item)) {
  187. $pic_list[] = Html::encode(trim($item));
  188. }
  189. }
  190. }
  191. $refund->pic_list = json_encode($pic_list, JSON_UNESCAPED_UNICODE);
  192. $refund->status = 0;
  193. $orderTransit = \app\models\OrderTransit::findOne(['order_id' => $order->id, 'is_delete' => 0]);
  194. if($orderTransit && $this->stbz_apply_data){
  195. $form = new \app\modules\admin\models\MerchantForm();
  196. $form->store_id = $this->store_id;
  197. $form->order_id = $orderTransit->cloud_order_id;
  198. $form->apply_data = $this->stbz_apply_data ?? [];
  199. $form->apply_data['type'] = $this->type;
  200. $form->apply_data['desc'] = $this->desc;
  201. $form->apply_data['pic_list'] = $this->pic_list;
  202. $mchOrderRefundApply = $form->mchOrderRefundApply();
  203. if($mchOrderRefundApply['code']){
  204. return $mchOrderRefundApply;
  205. }
  206. }
  207. if ($refund->save()) {
  208. // 标记商品申请过售后
  209. foreach ($order_detail_id as $value) {
  210. $order_detail = OrderDetail::findOne($value);
  211. $order_detail->is_refund = 1;
  212. $order_detail->save();
  213. }
  214. // 售后订单申请成功之后,相关操作
  215. $form = new OrderComplete();
  216. $form->order_id = $order->id;
  217. $form->order_type = 0;
  218. $form->form_id = $this->form_id;
  219. $form->order_refund_no = $refund->order_refund_no;
  220. $form->store_id = $order->store_id;
  221. $form->refund();
  222. $merchant = new MerchantForm();
  223. $merchant->order_id = $order->id;
  224. $merchant->syncMchOrderRefundStatus(1);
  225. return [
  226. 'code' => 0,
  227. 'msg' => '售后订单提交成功',
  228. ];
  229. } else {
  230. return [
  231. 'code' => 1,
  232. 'msg' => implode(';', array_values($refund->firstErrors))
  233. ];
  234. }
  235. }
  236. private function getOrderRefundNo()
  237. {
  238. $order_refund_no = null;
  239. while (true) {
  240. $order_refund_no = date('YmdHis') . mt_rand(100000, 999999);
  241. $exist_order_refund_no = OrderRefund::find()->where(['order_refund_no' => $order_refund_no])->exists();
  242. if (!$exist_order_refund_no) {
  243. break;
  244. }
  245. }
  246. return $order_refund_no;
  247. }
  248. }