OrderRefundForm.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models;
  8. use app\models\AccountLog;
  9. use app\models\Goods;
  10. use app\models\OrderTransit;
  11. use app\models\RefundAddress;
  12. use app\utils\OrderNo;
  13. use app\utils\Refund;
  14. use yii\base\Model;
  15. use app\models\Order;
  16. use app\models\OrderDetail;
  17. use app\models\OrderRefund;
  18. use app\models\User;
  19. use app\models\VerifyCardSale;
  20. use app\utils\Notice\NoticeSend;
  21. use app\utils\Tools;
  22. /**
  23. * 售后订单结果处理
  24. */
  25. class OrderRefundForm extends Model
  26. {
  27. public $store_id;
  28. public $order_refund_id;
  29. public $type;
  30. public $action;
  31. public $address_id;
  32. public $refund_price;
  33. public $refund;//是否退款
  34. public $orderType; //退款订单类型
  35. public $remark;
  36. public function rules()
  37. {
  38. return [
  39. [['order_refund_id', 'type', 'action'], 'required'],
  40. [['refund'], 'safe'],
  41. [['refund_price',], 'number', 'min' => 0,],
  42. [['address_id'], 'integer'],
  43. [['remark'], 'string'],
  44. ];
  45. }
  46. public function attributeLabels()
  47. {
  48. return [
  49. 'refund_price' => '退款金额',
  50. 'orderType' => '订单类型',
  51. ];
  52. }
  53. public function save($type = 0)
  54. {
  55. if (!$this->validate()) {
  56. return [
  57. 'code' => 1,
  58. 'msg' => $this->getErrorSummary(false)[0],
  59. ];
  60. }
  61. $order_refund = OrderRefund::find()->where([
  62. 'id' => $this->order_refund_id,
  63. 'store_id' => $this->store_id,
  64. 'is_delete' => Order::IS_DELETE_FALSE,
  65. ])->one();
  66. if (!$order_refund) {
  67. return [
  68. 'code' => 1,
  69. 'msg' => '售后订单不存在,请刷新页面'
  70. ];
  71. }
  72. $OrderDetail = OrderDetail::find()->where(['in','id',json_decode($order_refund['order_detail_id'], true)])->asArray()->all();
  73. $arr = [];
  74. $verifyids = '';
  75. foreach ($OrderDetail as $val) {
  76. $arr[] = $val['goods_id'];
  77. }
  78. // 订单时间
  79. $Order = Order::findOne(['id' => $order_refund['order_id']]);
  80. if (!$type) {
  81. $orderTransit = OrderTransit::findOne(['order_id' => $order_refund['order_id'], 'is_delete' => 0]);
  82. if (intval($orderTransit->cancel_examine) === 1) {
  83. return [
  84. 'code' => 1,
  85. 'msg' => '售后订单已提交云仓 不可重复操作'
  86. ];
  87. }
  88. }
  89. $created_at = $Order['created_at'];
  90. $confirm_time = $Order['confirm_time'];
  91. foreach ($arr as $v) {
  92. // 获取核销卡id
  93. $verifyids = explode(',',Goods::findOne(['id' => $v])->verify_card_id);
  94. if (!empty($verifyids)) {
  95. $veirfysales = VerifyCardSale::find()
  96. ->where(['in', 'verify_card_id', $verifyids])
  97. ->andWhere(['in', 'goods_id', $arr])
  98. ->andWhere(['>' , 'created_at', $created_at])
  99. ->andWhere(['<=' , 'created_at', $confirm_time])
  100. ->andWhere(['store_id' => $order_refund['store_id']])
  101. ->andWhere(['user_id' => $order_refund['user_id']])
  102. ->asArray()->all();
  103. foreach ($veirfysales as $val) {
  104. $verifysale = VerifyCardSale::findOne(['id' => $val['id']]);
  105. $verifysale->status = 2;
  106. $verifysale->save();
  107. }
  108. }
  109. }
  110. if ($order_refund->status != 0) {
  111. return [
  112. 'code' => 1,
  113. 'msg' => '售后订单已经处理过了,请刷新页面',
  114. 'id' => $order_refund->id,
  115. ];
  116. }
  117. if ($this->type == 1) {
  118. return $this->submit1($order_refund);
  119. }
  120. if ($this->type == 2) {
  121. return $this->submit2($order_refund);
  122. }
  123. }
  124. /**
  125. * 平台订单退货退款
  126. * @param $order_refund
  127. * @return \app\cyy\ValidationErrorResponse|array
  128. */
  129. private function submit1($order_refund)
  130. {
  131. $order = Order::findOne($order_refund->order_id);
  132. if ($this->action == 1) {//同意
  133. if ($this->refund != 1) {
  134. //仅同意,还未退款
  135. if (isset($this->refund_price)) {
  136. // 这里同意审核的只会走一次 在执行的时候order_refund表中的refund_price是实际支付的金额 这里要判断减去已退款的金额
  137. $rmAllSum = \app\models\OrderRefundMoney::find()->where(['is_delete' => 0, 'status' => 1, 'order_id' => $order['id']])->sum('refund_price') ?? 0;
  138. $canRefundPrice = $order_refund->refund_price - $rmAllSum;
  139. if ($this->refund_price > $canRefundPrice) {
  140. return [
  141. 'code' => 1,
  142. 'msg' => '退款金额不能大于' . $canRefundPrice,
  143. ];
  144. }
  145. $order_refund->refund_price = $this->refund_price;
  146. }
  147. if (!$this->address_id) {
  148. return [
  149. 'code' => 1,
  150. 'msg' => '退货地址不能为空',
  151. ];
  152. };
  153. $refundAddress = RefundAddress::findOne($this->address_id);
  154. if ($refundAddress) {
  155. $order_refund->refund_address = json_encode([
  156. 'name' => $refundAddress->name,
  157. 'address' => $refundAddress->address,
  158. 'mobile' => $refundAddress->mobile
  159. ], JSON_UNESCAPED_UNICODE);
  160. }
  161. $order_refund->address_id = $this->address_id;
  162. $order_refund->is_agree = 1;
  163. $order_refund->save();
  164. if ($order_refund->save()) {
  165. return [
  166. 'code' => 0,
  167. 'msg' => '已同意退货。',
  168. ];
  169. } else {
  170. return [
  171. 'code' => 1,
  172. 'msg' => $order_refund->errors[0],
  173. ];
  174. }
  175. } else {
  176. //已同意,退款操作
  177. $order_refund->status = 1;
  178. $order_refund->response_time = time();
  179. if ($order_refund->refund_price > 0 && (in_array($order->pay_type, [Order::PAY_TYPE_WX_B2B, Order::PAY_TYPE_ADAPAY_WX, Order::PAY_TYPE_ADAPAY_ALIPAY, Order::PAY_TYPE_KEY_ADAPAY_QUICKPAY_FRONTPAY, Order::PAY_TYPE_HUIFU_V2_JSPAY_WX, Order::PAY_TYPE_WECHAT, Order::PAY_TYPE_ALI]))) {
  180. $res = Refund::refund($order, OrderNo::ORDER_MALL, $order_refund->order_refund_no, $order_refund->refund_price);
  181. if ($res !== true) {
  182. return $res;
  183. }
  184. }
  185. // 商城商品总库存恢复
  186. $order_detail_list = OrderDetail::find()->where(['order_id' => $order->id, 'is_delete' => 0])->all();
  187. foreach ($order_detail_list as $order_detail) {
  188. $goods = Goods::findOne($order_detail->goods_id);
  189. $attr_id_list = [];
  190. foreach (json_decode($order_detail->attr) as $item) {
  191. array_push($attr_id_list, $item->attr_id);
  192. }
  193. $goods->numAdd($attr_id_list, $order_detail->num);
  194. }
  195. $user = User::findOne(['id' => $order->user_id]);
  196. if($order['giving_gifts_received_user_id']){
  197. $user = User::findOne($order['giving_gifts_received_user_id']);
  198. }
  199. $balance = isset($order->balance) ? $order->balance : 0;
  200. if ($balance > 0) {
  201. $before = $user->money;
  202. $user->money += $balance;
  203. $log = new AccountLog();
  204. $log->store_id = $this->store_id ?? get_store_id();
  205. $log->user_id = $user->id;
  206. $log->type = AccountLog::TYPE_GOODS_BALANCE;
  207. $log->amount = $balance;
  208. $log->log_type = AccountLog::LOG_TYPE_INCOME;
  209. $log->desc = "商城售后订单退款,商品余额抵扣:退款订单号:{$order_refund->order_refund_no}";
  210. $log->before = $before;
  211. $log->after = $user->money;
  212. $log->operator = '';
  213. $log->operator_id = 0;
  214. $log->operator_type = AccountLog::TYPE_OPERATOR_NORMAL;
  215. $log->created_at = time();
  216. $log->order_id = $order->id;
  217. $log->order_type = AccountLog::TYPE_PLATFORM_REFUND_ORDER;
  218. if (!$log->save()) {
  219. return [
  220. 'code' => 1,
  221. 'msg' => implode(';', array_values($log->firstErrors))
  222. ];
  223. };
  224. if (!$user->save()) {
  225. return [
  226. 'code' => 1,
  227. 'msg' => $this->getErrorSummary(false)[0],
  228. ];
  229. }
  230. }
  231. $integral = isset($order->integral) ? json_decode($order->integral)->forehead_integral : 0;
  232. if ($integral > 0) {
  233. $user->integral += $integral;
  234. }
  235. if ($order_refund->refund_price > 0 && $order->pay_type == 3) {
  236. $before = $user->money;
  237. $user->money += floatval($order_refund->refund_price);
  238. $log = new AccountLog();
  239. $log->store_id = $this->store_id ?? get_store_id();
  240. $log->user_id = $user->id;
  241. $log->type = AccountLog::TYPE_BALANCE;
  242. $log->amount = $order_refund->refund_price;
  243. $log->log_type = AccountLog::LOG_TYPE_INCOME;
  244. $log->desc = "商城售后订单退款:退款订单号:{$order_refund->order_refund_no}";
  245. $log->before = $before;
  246. $log->after = $user->money;
  247. $log->operator = '';
  248. $log->operator_id = 0;
  249. $log->operator_type = AccountLog::TYPE_OPERATOR_NORMAL;
  250. $log->created_at = time();
  251. $log->order_id = $order->id;
  252. $log->order_type = AccountLog::TYPE_PLATFORM_REFUND_ORDER;
  253. if (!$log->save()) {
  254. return [
  255. 'code' => 1,
  256. 'msg' => implode(';', array_values($log->firstErrors))
  257. ];
  258. };
  259. if (!$user->save()) {
  260. return [
  261. 'code' => 1,
  262. 'msg' => $this->getErrorSummary(false)[0],
  263. ];
  264. }
  265. }
  266. if ($order_refund->save()) {
  267. // 删除赠送的核销卡
  268. VerifyCardSale::cancelCard($order);
  269. $goods = Goods::findOne(OrderDetail::findOne(['order_id' => $order->id])->goods_id);
  270. NoticeSend::OrderRefund($order->user_id, $order->mobile, $order->order_no, $order_refund->refund_price, $goods->name);
  271. $res = \queue_push(new \app\jobs\AlipayThirdOrderJob(['order_id' => $order->id]), 5);
  272. return [
  273. 'code' => 0,
  274. 'msg' => '处理成功,已完成退款退货。',
  275. ];
  276. }
  277. return [
  278. 'code' => 1,
  279. 'msg' => $this->getErrorSummary(false)[0],
  280. ];
  281. }
  282. }
  283. if ($this->action == 2) {//拒绝
  284. $order_refund->status = 3;
  285. $order_refund->refuse_desc = $this->remark ? $this->remark : '卖家拒绝了您的退货请求';
  286. $order_refund->response_time = time();
  287. if ($order_refund->save()) {
  288. NoticeSend::OrderRefundCancel($order->mobile);
  289. $merchant = new MerchantForm();
  290. $merchant->order_id = $order->id;
  291. $merchant->syncMchOrderRefundStatus(0);
  292. return [
  293. 'code' => 0,
  294. 'msg' => '处理成功,已拒绝该退货退款订单。',
  295. ];
  296. }
  297. return [
  298. 'code' => 1,
  299. 'msg' => $this->getErrorSummary(false)[0],
  300. ];
  301. }
  302. }
  303. /**
  304. * 统一处理换货
  305. * @param $order_refund
  306. * @return \app\cyy\ValidationErrorResponse|array
  307. */
  308. private function submit2($order_refund)
  309. {
  310. if ($this->action == 1) {//同意
  311. $order_refund->status = 2;
  312. if (!$this->address_id) {
  313. return [
  314. 'code' => 1,
  315. 'msg' => '退货地址不能为空',
  316. ];
  317. };
  318. $order_refund->address_id = $this->address_id;
  319. $order_refund->response_time = time();
  320. if ($order_refund->save()) {
  321. // TODO: 消息
  322. return [
  323. 'code' => 0,
  324. 'msg' => '处理成功,已同意换货。',
  325. ];
  326. }
  327. return [
  328. 'code' => 1,
  329. 'msg' => $this->getErrorSummary(false)[0],
  330. ];
  331. }
  332. if ($this->action == 2) {//拒绝
  333. $order_refund->status = 3;
  334. $order_refund->refuse_desc = $this->remark ? $this->remark : '卖家已拒绝您的换货请求';
  335. $order_refund->response_time = time();
  336. if ($order_refund->save()) {
  337. $merchant = new MerchantForm();
  338. $merchant->order_id = $order_refund->order_id;
  339. $merchant->syncMchOrderRefundStatus(0);
  340. return [
  341. 'code' => 0,
  342. 'msg' => '处理成功,已拒绝换货请求。',
  343. ];
  344. }
  345. return [
  346. 'code' => 1,
  347. 'msg' => $this->getErrorSummary(false)[0],
  348. ];
  349. }
  350. }
  351. }