OrderRefundListForm.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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\Admin;
  9. use app\models\common\admin\order\CommonOrderSearch;
  10. use app\models\Goods;
  11. use app\models\Md;
  12. use app\models\Order;
  13. use app\models\OrderDetail;
  14. use app\models\OrderGoodsCancel;
  15. use app\models\OrderRefund;
  16. use app\models\OrderTransit;
  17. use app\models\RefundAddress;
  18. use app\models\Salesman;
  19. use app\models\Store;
  20. use app\models\User;
  21. use app\utils\Export;
  22. use app\utils\ExportList;
  23. use yii\base\Model;
  24. use yii\helpers\Json;
  25. class OrderRefundListForm extends Model
  26. {
  27. public $export;
  28. public $store_id;
  29. public $user_id;
  30. public $keyword;
  31. public $status;
  32. public $dateStart;
  33. public $dateEnd;
  34. public $keywordType;
  35. public $platform; //所属平台
  36. public $flag;
  37. public $fields;
  38. public $salesman_id;
  39. public $activity_type;
  40. public $goods_name;
  41. public $mch;
  42. public $mch_id;
  43. // 已处理状态
  44. const IS_HANDLE_STATUS = 1;
  45. public function rules()
  46. {
  47. return [
  48. [['keyword', 'flag'], 'trim'],
  49. [['flag', 'goods_name'], 'string'],
  50. [['status', 'user_id', 'keywordType', 'salesman_id'], 'integer'],
  51. [['status'], 'default', 'value' => -1],
  52. [['dateStart', 'dateEnd'], 'trim'],
  53. [['export', 'activity_type'], 'safe'],
  54. [['mch', 'mch_id'], 'safe'],
  55. [['fields'],'safe']
  56. ];
  57. }
  58. public function search($params = [])
  59. {
  60. if (!$this->validate()) {
  61. return [
  62. 'code' => 1,
  63. 'msg' => $this->getErrorSummary(false)[0],
  64. ];
  65. }
  66. $query = OrderRefund::find()->alias('or')
  67. ->leftJoin(['o' => Order::tableName()], 'o.id=or.order_id')
  68. ->leftJoin(['od' => OrderDetail::tableName()], 'od.order_id=o.id')
  69. ->leftJoin(['u' => User::tableName()], 'u.id=or.user_id')
  70. ->where(['or.is_delete' => Order::IS_DELETE_FALSE,
  71. 'o.is_show' => Order::IS_SHOW_TRUE]);
  72. if($this->activity_type == Order::ACTIVITY_TYPE_CUT_PRICE){
  73. $query->andWhere(['>', 'o.activity_cut_price_order_id', 0]);
  74. }
  75. if ($this->status == OrderRefund::STATUS_IN) {
  76. $query->andWhere(['AND', ['or.status' => OrderRefund::STATUS_IN], ['or.is_user_cancel' => 0]]);
  77. }
  78. if ($this->status == self::IS_HANDLE_STATUS) {
  79. $query->andWhere(['OR', ['in', 'or.status', OrderRefund::$is_handle_status], ['or.is_user_cancel' => 1]]);
  80. }
  81. if ($this->goods_name) {
  82. $query->andWhere(['LIKE', 'od.goods_name', $this->goods_name]);
  83. }
  84. if (get_md_id()) {
  85. $query->andWhere(['or.md_id' => get_md_id()]);
  86. }
  87. $admin = get_admin();
  88. $admin_id = $admin->id;
  89. if ($admin->username == 'admin') {
  90. $admin_id = null;
  91. }
  92. if ($admin_id) {
  93. if ($this->store_id < 0) {
  94. $salesman_id = $this->salesman_id;
  95. $salesman_where = [
  96. 'admin_id' => $admin_id,
  97. 'is_delete' => 0
  98. ];
  99. if ($salesman_id) {
  100. $salesman_where['id'] = $salesman_id;
  101. }
  102. $ids = Salesman::find()->where($salesman_where)->select('id')->asArray()->all();
  103. // $ids = Salesman::find()->where(['admin_id' => $admin_id, 'is_delete' => 0])->select('id')->asArray()->all();
  104. $admin_model = Admin::findOne($admin_id);
  105. $area_level = $admin_model->area_level;
  106. $store_query = Store::find()->where(['is_delete' => 0]);
  107. if ($this->salesman_id) {
  108. $store_query->andWhere(['in', 'salesman_id', array_column($ids, 'id')]);
  109. } else {
  110. if($area_level == 1){
  111. $store_query->andWhere([
  112. 'or',
  113. ['province_id' => $admin_model->province_id, 'city_id' => $admin_model->city_id, 'district_id' => $admin_model->district_id],
  114. ['admin_id' => $admin_id],
  115. ['in', 'salesman_id', array_column($ids, 'id')]
  116. ]);
  117. } elseif ($area_level == 2){
  118. $store_query->andWhere([
  119. 'or',
  120. ['province_id' => $admin_model->province_id, 'city_id' => $admin_model->city_id],
  121. ['admin_id' => $admin_id],
  122. ['in', 'salesman_id', array_column($ids, 'id')]
  123. ]);
  124. } elseif ($area_level == 3){
  125. $store_query->andWhere([
  126. 'or',
  127. ['province_id' => $admin_model->province_id],
  128. ['admin_id' => $admin_id],
  129. ['in', 'salesman_id', array_column($ids, 'id')]
  130. ]);
  131. } else {
  132. $store_query->andWhere([
  133. 'or',
  134. ['admin_id' => $admin_id],
  135. ['in', 'salesman_id', array_column($ids, 'id')]
  136. ]);
  137. }
  138. }
  139. $ids = $store_query->select('id')->column();
  140. }
  141. }
  142. if (!empty($ids)) {
  143. $query->andWhere(['or.store_id' => $ids]);
  144. } else {
  145. $query->andWhere([
  146. 'or.store_id' => $this->store_id
  147. ]);
  148. }
  149. if (!empty($params['order_no'])) {
  150. $query->andWhere(['like', 'o.order_no', $params['order_no']]);
  151. }
  152. $query->groupBy("or.order_detail_id, or.is_user_cancel");
  153. $commonOrderSearch = new CommonOrderSearch();
  154. // $query = $commonOrderSearch->search($query, $this);
  155. $query = $commonOrderSearch->keyword($query, $this->keywordType, $this->keyword);
  156. if ($this->flag == Export::EXPORT) {
  157. $query_export = clone $query;
  158. $list_ex = $query_export->orderBy('or.created_at DESC')->select('or.id order_refund_id,o.id order_id,
  159. o.order_no,o.name,o.mobile,o.address,u.nickname,or.order_refund_no,
  160. u.id user_id,or.created_at,
  161. or.type refund_type,or.status refund_status,or.desc refund_desc,or.pic_list refund_pic_list,
  162. or.refund_price,or.refuse_desc refund_refuse_desc,g.attr goods_attr')->asArray()->all();
  163. // g.name goods_name,g.id goods_id,od.total_price,g.attr goods_attr,od.num,od.attr,od.total_price
  164. foreach ($list_ex as $i => $new) {
  165. $order_detail = OrderDetail::findOne($new['order_id']);
  166. $list_ex[$i]['goods_name'] = $order_detail->goods_name;
  167. $list_ex[$i]['goods_id'] = $order_detail->goods_id;
  168. $list_ex[$i]['num'] = $order_detail->num;
  169. $list_ex[$i]['total_price'] = $order_detail->total_price;
  170. $list_ex[$i]['attr'] = $order_detail->attr;
  171. }
  172. $f = new ExportList();
  173. $f->fields = $this->fields;
  174. $f->refundForm($list_ex);
  175. }
  176. $query->orderBy('or.id DESC')->select('or.is_user_cancel, or.order_detail_id, or.id order_refund_id, o.id order_id, o.order_no, o.name,
  177. o.mch_id,,or.order_refund_no,
  178. o.mobile, o.address, o.pay_type, u.nickname, u.id user_id, u.platform, or.created_at, or.type refund_type,
  179. or.status refund_status, or.desc refund_desc, or.pic_list refund_pic_list, or.refund_price, or.refuse_desc refund_refuse_desc,
  180. or.is_agree, or.is_user_send, or.user_send_express, or.user_send_express_no, or.op_admin_name, o.md_id');
  181. // g.name goods_name,g.id goods_id,od.num,od.attr,od.total_price
  182. if (isset($this->mch) && $this->mch == 1) {
  183. if ($this->mch_id > 0) {
  184. $query->andWhere(['o.mch_id' => $this->mch_id]);
  185. }else{
  186. $query->andWhere(['>', 'o.mch_id', 0]);
  187. }
  188. }else{
  189. $query->andWhere(['o.mch_id' => 0]);
  190. }
  191. $pagination = pagination_make($query);
  192. $list = $pagination['list'];
  193. foreach ($list as $i => $item) {
  194. $cancel_order_id = OrderGoodsCancel::getCancelGoodsOrderQuery($item['order_id'], 'order_detail_id', null)
  195. ->select('order_detail_id')->column();
  196. $order_detail = OrderDetail::find()->alias('od')->leftJoin(['g' => Goods::tableName()], 'g.id=od.goods_id')->where(['od.order_id' => $item['order_id'], 'od.is_refund' => 1])
  197. ->andWhere(['in', 'od.id', Json::decode($item['order_detail_id'])])->andWhere(['NOT IN', 'od.id', $cancel_order_id])
  198. ->select('od.goods_name as name, od.delivery_type, od.total_price, od.num, od.attr, g.attr as attr_list, od.pic, g.cover_pic as goods_pic')->asArray()->all();
  199. $list[$i]['goods_list'] = $order_detail;
  200. $list[$i]['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  201. $list[$i]['refund_pic_list'] = json_decode($item['refund_pic_list']);
  202. $item['md_info'] = null;
  203. if ($list[$i]['md_id']) {
  204. $list[$i]['md_info'] = Md::findOne($item['md_id']);
  205. }
  206. $rmSum = \app\models\OrderRefundMoney::find()->where(['is_delete' => 0, 'status' => 1, 'order_id' => $item['order_id']])->sum('refund_price');
  207. $rmSum && $list[$i]['refund_price_text'] = $item['refund_price'].' / 已退' . $rmSum;
  208. $list[$i]['has_refund_price'] += $rmSum;
  209. $list[$i]['can_refund_price'] = $rmSum < $list[$i]['refund_price'];
  210. //商家点击同意申请售后调用云仓申请售后接口
  211. //以下为调用云仓申请售后接口所用参数
  212. $reasonsType = null;
  213. $returnType = null;
  214. $packageType = null;
  215. $serviceType = null;
  216. $orderTransit = OrderTransit::findOne(['order_id' => $item['order_id'], 'is_delete' => 0]);
  217. $list[$i]['cloud_cancel_examine'] = 1;//如果是已经申请售后则商城不显示退款退货按钮
  218. if ($orderTransit) {
  219. if (intval($orderTransit->cancel_examine) === 0) {
  220. $form = new MerchantForm();
  221. $token = get_merchant_token();
  222. $result = $form->stbzRrfundOrderHandleInfo($token, $orderTransit->cloud_order_id);
  223. if ($result['code'] === 0) {
  224. $reasonsType = $result['data']['reasonsType'];
  225. $returnType = $result['data']['returnType'];
  226. $packageType = $result['data']['packageType'];
  227. $serviceType = $result['data']['serviceType'];
  228. }
  229. } else {
  230. $cancel_examine_info = json_decode($orderTransit->cancel_examine_info, true) ?? [];
  231. $transit_order_detail_id = array_column($cancel_examine_info, 'store_order_detail_id');
  232. $list[$i]['cloud_cancel_examine'] = 0;
  233. $open = false;
  234. $order_detail_id = json_decode($item['order_detail_id'], true);
  235. foreach ($transit_order_detail_id as $transit_detail_item) {
  236. foreach ($order_detail_id as $detail_item) {
  237. if ($transit_detail_item == $detail_item) {
  238. $open = true;
  239. }
  240. }
  241. }
  242. if (!$open) {
  243. $list[$i]['cloud_cancel_examine'] = 1;
  244. }
  245. }
  246. }
  247. $list[$i]['cloud_order_price'] = $item['refund_price'] ?? 0;
  248. $list[$i]['reasonsType'] = $reasonsType;
  249. $list[$i]['returnType'] = $returnType;
  250. $list[$i]['packageType'] = $packageType;
  251. $list[$i]['serviceType'] = $serviceType;
  252. $list[$i]['is_tran'] = !empty($orderTransit) ? 1 : 0;
  253. $list[$i]['cloud_order_id'] = $orderTransit->cloud_order_id ?? 0;
  254. $list[$i]['order_refund_no'] = $item['order_refund_no'];
  255. $orderRefund = OrderRefund::find()->where(['id' => $item['order_refund_id']])->asArray()->one();
  256. $list[$i]['refund_status_desc'] = OrderRefund::getTypeText($orderRefund);
  257. }
  258. $address = RefundAddress::find()->where(['store_id' => $this->store_id, 'mch_id' => 0, 'is_delete' => 0])->all();
  259. if ($this->mch_id > 0) {
  260. $address = RefundAddress::find()->where(['mch_id' => $this->mch_id, 'is_delete' => 0])->all();
  261. }
  262. foreach ($address as &$v) {
  263. if (mb_strlen($v->address) > 20) {
  264. $v->address = mb_substr($v->address, 0, 20) . '···';
  265. }
  266. }
  267. unset($v);
  268. // 获取可导出数据
  269. $f = new ExportList();
  270. $f->type = 1;
  271. $exportList = $f->getList();
  272. if($this->export){
  273. return $this->export($list);
  274. }
  275. return [
  276. 'code' => 0,
  277. 'msg' => 'success',
  278. 'data' => [
  279. 'q' => $query->createCommand()->getRawSql(),
  280. 'export_list' => $exportList,
  281. 'data' => $list,
  282. 'address' => $address,
  283. 'pageNo' => $pagination['pageNo'],
  284. 'totalCount' => $pagination['totalCount'],
  285. ],
  286. ];
  287. }
  288. private function export($list) {
  289. $rows = [[
  290. '会员信息',
  291. '订单号',
  292. '售后单号',
  293. '售后类型',
  294. '退款金额(元)',
  295. '商品',
  296. '买家/收货人',
  297. '买家/收货人手机号',
  298. '下单门店',
  299. '时间',
  300. ]];
  301. foreach($list as $item){
  302. $refund_type = '换货';
  303. if($item['refund_type'] == 1){
  304. $refund_type = '退款退货';
  305. }
  306. $goods = [];
  307. foreach ($item['goods_list'] as $i => $gitem) {
  308. $attr = [];
  309. $gitem['attr_list'] = json_decode($gitem['attr_list'], true);
  310. foreach ($gitem['attr_list'] as $atitem) {
  311. $attr[] = isset($atitem['attr_name']) ? $atitem['attr_name'] : '';
  312. }
  313. $goods[] = $gitem['name'] . '(' . implode(',', $attr) . ')' . '(' . $gitem['num'] . $gitem['unit'] . ')' . '(' . $gitem['total_price'] . '元)';
  314. }
  315. $r = [
  316. $item['nickname'],
  317. $item['order_no'],
  318. $item['order_refund_no'],
  319. $refund_type,
  320. $item['refund_price'],
  321. '【' . implode('】,【', $goods) . '】',
  322. $item['name'],
  323. $item['mobile'],
  324. isset($item['md_info']) ? $item['md_info']['name'] : '',
  325. $item['created_at'],
  326. ];
  327. $rows[] = $r;
  328. }
  329. $writer = \Spatie\SimpleExcel\SimpleExcelWriter::streamDownload(time() . '.xlsx')->noHeaderRow()
  330. ->addRows($rows)->toBrowser();
  331. }
  332. }