OrderController.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. <?php
  2. namespace addons\TinyShop\merchant\modules\order\controllers;
  3. use Yii;
  4. use yii\data\Pagination;
  5. use yii\web\NotFoundHttpException;
  6. use yii\web\UnprocessableEntityHttpException;
  7. use common\enums\StatusEnum;
  8. use common\enums\PayTypeEnum;
  9. use common\forms\CreditsLogForm;
  10. use common\helpers\ArrayHelper;
  11. use common\helpers\ResultHelper;
  12. use addons\TinyShop\common\enums\OrderStatusEnum;
  13. use addons\TinyShop\common\models\order\Order;
  14. use addons\TinyShop\merchant\controllers\BaseController;
  15. use addons\TinyShop\merchant\modules\order\forms\OrderSearchForm;
  16. use addons\TinyShop\common\enums\SubscriptionActionEnum;
  17. use addons\TinyShop\common\enums\RefundStatusEnum;
  18. use addons\TinyShop\common\models\product\Product;
  19. use addons\TinyShop\merchant\modules\order\forms\OrderStoreForm;
  20. use addons\TinyShop\merchant\modules\order\forms\ProductExpressForm;
  21. use addons\TinyShop\common\enums\ProductExpressShippingTypeEnum;
  22. /**
  23. * Class OrderController
  24. * @package addons\TinyShop\merchant\modules\order\controllers
  25. * @author jianyan74 <751393839@qq.com>
  26. */
  27. class OrderController extends BaseController
  28. {
  29. /**
  30. * @var Order
  31. */
  32. public $modelClass = Order::class;
  33. /**
  34. * 首页
  35. *
  36. * @return mixed
  37. */
  38. public function actionIndex()
  39. {
  40. $search = new OrderSearchForm();
  41. $search->attributes = Yii::$app->request->get();
  42. // 退款中
  43. if ($search->order_status == OrderStatusEnum::REFUND_ING) {
  44. $search->order_status = '';
  45. $search->is_after_sale = StatusEnum::ENABLED;
  46. }
  47. $data = Order::find()
  48. ->alias('o')
  49. ->where(['>=', 'status', StatusEnum::DISABLED])
  50. ->andFilterWhere(['pay_type' => $search->pay_type])
  51. ->andFilterWhere(['order_from' => $search->order_from])
  52. ->andFilterWhere(['order_type' => $search->order_type])
  53. ->andFilterWhere(['shipping_type' => $search->shipping_type])
  54. ->andFilterWhere(['is_after_sale' => $search->is_after_sale])
  55. ->andFilterWhere(['marketing_id' => $search->marketing_id])
  56. ->andFilterWhere(['marketing_type' => $search->marketing_type])
  57. ->andFilterWhere(['wholesale_record_id' => $search->wholesale_record_id])
  58. ->andFilterWhere(['store_id' => Yii::$app->params['store_id']])
  59. ->andFilterWhere(['merchant_id' => $this->getMerchantId()])
  60. ->andFilterWhere($search->getBetweenTime())
  61. ->andFilterWhere($search->getKeyword())
  62. ->andFilterWhere($search->getKeyword())
  63. ->with(['member', 'product'])->andFilterWhere(['order_status' => $search->order_status]);
  64. $pages = new Pagination(['totalCount' => $data->count(), 'pageSize' => $this->pageSize]);
  65. $models = $data->offset($pages->offset)
  66. ->orderBy('id desc')
  67. ->limit($pages->limit)
  68. ->all();
  69. return $this->render($this->action->id, [
  70. 'models' => $models,
  71. 'pages' => $pages,
  72. 'search' => $search,
  73. 'total' => Yii::$app->tinyShopService->order->findCount(),
  74. 'receiptPrinter' => Yii::$app->services->extendPrinter->findAllAuto(Yii::$app->services->merchant->getNotNullId()),
  75. ]);
  76. }
  77. /**
  78. * @param $id
  79. * @return string
  80. */
  81. public function actionDetail($id)
  82. {
  83. /** @var Order $model */
  84. $model = Order::find()
  85. ->where(['id' => $id])
  86. // ->andWhere(['>=', 'status', StatusEnum::DISABLED])
  87. ->andFilterWhere(['merchant_id' => $this->getMerchantId()])
  88. ->with(['member', 'invoice', 'product', 'expressCompany', 'productExpress', 'marketingDetail', 'payLog'])
  89. ->one();
  90. $product = ArrayHelper::toArray($model->product);
  91. $productExpress = ArrayHelper::toArray($model->productExpress);
  92. // 重组发货
  93. foreach ($productExpress as &$express) {
  94. $express['product'] = [];
  95. foreach ($product as $key => $item) {
  96. if (in_array($item['id'], $express['order_product_ids'])) {
  97. $express['product'][] = $item;
  98. unset($product[$key]);
  99. }
  100. }
  101. }
  102. // 合并营销显示
  103. $marketingDetails = Yii::$app->tinyShopService->marketing->mergeIdenticalMarketing($model['marketingDetail'] ?? []);
  104. return $this->render($this->action->id, [
  105. 'model' => $model,
  106. 'product' => $product,
  107. 'productExpress' => $productExpress,
  108. 'marketingDetails' => $marketingDetails,
  109. 'orderAction' => Yii::$app->services->actionLog->findByBehavior('order', $id, 'TinyShop'),
  110. ]);
  111. }
  112. /**
  113. * 线下支付
  114. *
  115. * @param $id
  116. * @return mixed
  117. */
  118. public function actionPay($id)
  119. {
  120. // 开启事务
  121. $transaction = Yii::$app->db->beginTransaction();
  122. try {
  123. $order = $this->findModel($id);
  124. Yii::$app->tinyShopService->order->pay($order, PayTypeEnum::OFFLINE);
  125. $transaction->commit();
  126. return $this->message('线下支付成功', $this->redirect(Yii::$app->request->referrer));
  127. } catch (\Exception $e) {
  128. $transaction->rollBack();
  129. return $this->message($e->getMessage(), $this->redirect(Yii::$app->request->referrer), 'error');
  130. }
  131. }
  132. /**
  133. * 确认收货
  134. *
  135. * @param $id
  136. * @return array
  137. */
  138. public function actionTakeDelivery($id)
  139. {
  140. try {
  141. Yii::$app->tinyShopService->order->takeDelivery($id);
  142. return ResultHelper::json(200, '操作成功');
  143. } catch (\Exception $e) {
  144. return ResultHelper::json(422, $e->getMessage());
  145. }
  146. }
  147. /**
  148. * 提货
  149. *
  150. * @param $id
  151. * @return mixed|string
  152. * @throws NotFoundHttpException
  153. * @throws \yii\base\ExitException
  154. */
  155. public function actionPickup($id)
  156. {
  157. $order = $this->findModel($id);
  158. $model = OrderStoreForm::findOne(['order_id' => $order->id]);
  159. // ajax校验
  160. $this->activeFormValidate($model);
  161. if ($model->load(Yii::$app->request->post())) {
  162. // 进行无物流状态
  163. $productExpressForm = new ProductExpressForm();
  164. $productExpressForm->order = $order;
  165. $productExpressForm->order_id = $order->id;
  166. $productExpressForm->operator_id = Yii::$app->user->identity->id;
  167. $productExpressForm->operator_username = Yii::$app->user->identity->username;
  168. $productExpressForm->shipping_type = ProductExpressShippingTypeEnum::NOT_LOGISTICS;
  169. $productExpressForm->order_product_ids = ArrayHelper::getColumn($order->product, 'id');
  170. // 事务
  171. $transaction = Yii::$app->db->beginTransaction();
  172. try {
  173. if (!$model->save()) {
  174. throw new NotFoundHttpException($this->getError($model));
  175. }
  176. if (!$productExpressForm->save()) {
  177. throw new NotFoundHttpException($this->getError($productExpressForm));
  178. }
  179. // 进行收货
  180. Yii::$app->tinyShopService->order->takeDelivery($id);
  181. $transaction->commit();
  182. return $this->message('提货成功', $this->redirect(Yii::$app->request->referrer));
  183. } catch (\Exception $e) {
  184. $transaction->rollBack();
  185. return $this->message($e->getMessage(), $this->redirect(Yii::$app->request->referrer), 'error');
  186. }
  187. }
  188. return $this->renderAjax($this->action->id, [
  189. 'model' => $model,
  190. ]);
  191. }
  192. /**
  193. * 收货地址
  194. *
  195. * @param $id
  196. * @return mixed|string
  197. * @throws NotFoundHttpException
  198. * @throws \yii\base\ExitException
  199. */
  200. public function actionAddress($id)
  201. {
  202. $model = $this->findModel($id);
  203. $model->setScenario('address');
  204. $this->activeFormValidate($model);
  205. if ($model->load(Yii::$app->request->post())) {
  206. $model->receiver_name = Yii::$app->services->provinces->getCityListName([
  207. $model->receiver_province_id,
  208. $model->receiver_city_id,
  209. $model->receiver_area_id,
  210. ]);
  211. if ($model->save()) {
  212. Yii::$app->services->actionLog->create('order', '修改收货地址', $model->id);
  213. return $this->message('修改成功', $this->redirect(Yii::$app->request->referrer));
  214. }
  215. return $this->message($this->getError($model), $this->redirect(Yii::$app->request->referrer), 'error');
  216. }
  217. return $this->renderAjax($this->action->id, [
  218. 'model' => $model,
  219. ]);
  220. }
  221. /**
  222. * 备注
  223. *
  224. * @param $id
  225. * @return mixed|string
  226. * @throws NotFoundHttpException
  227. * @throws \yii\base\ExitException
  228. */
  229. public function actionSellerMemo($id)
  230. {
  231. $model = $this->findModel($id);
  232. $this->activeFormValidate($model);
  233. if ($model->load(Yii::$app->request->post())) {
  234. if ($model->save()) {
  235. // 记录操作
  236. Yii::$app->services->actionLog->create('order', '修改备注', $model->id);
  237. return $this->message('修改成功', $this->redirect(Yii::$app->request->referrer));
  238. }
  239. return $this->message($this->getError($model), $this->redirect(Yii::$app->request->referrer), 'error');
  240. }
  241. return $this->renderAjax($this->action->id, [
  242. 'model' => $model,
  243. ]);
  244. }
  245. /**
  246. * 关闭订单
  247. *
  248. * @param $id
  249. * @return array
  250. */
  251. public function actionClose($id)
  252. {
  253. try {
  254. Yii::$app->tinyShopService->order->close($id);
  255. // 记录操作
  256. Yii::$app->services->actionLog->create('orderClose', '管理员关闭订单', $id);
  257. return ResultHelper::json(200, '操作成功');
  258. } catch (\Exception $e) {
  259. return ResultHelper::json(422, $e->getMessage());
  260. }
  261. }
  262. /**
  263. * 订单退单
  264. *
  265. * @param $id
  266. * @return array
  267. */
  268. public function actionChargeback($id)
  269. {
  270. // 开启事务
  271. $transaction = Yii::$app->db->beginTransaction();
  272. try {
  273. /** @var Order $order */
  274. $order = $this->findModel($id);
  275. if (!empty($order->productExpress)) {
  276. throw new UnprocessableEntityHttpException('部分商品已发货,不支持退单');
  277. }
  278. $isCommission = false;
  279. // 原路退回
  280. $orderProducts = Yii::$app->tinyShopService->orderProduct->findByOrderId($id);
  281. foreach ($orderProducts as $orderProduct) {
  282. if ($orderProduct['order_status'] != OrderStatusEnum::PAY) {
  283. throw new UnprocessableEntityHttpException($orderProduct['product_name'] . '不处于支付状态');
  284. }
  285. if ($orderProduct['refund_money'] > 0) {
  286. throw new UnprocessableEntityHttpException($orderProduct['product_name'] . '已退款');
  287. }
  288. if (!in_array($orderProduct['refund_status'], RefundStatusEnum::deliver())) {
  289. throw new UnprocessableEntityHttpException($orderProduct['product_name'] . '退款状态未处理');
  290. }
  291. // 关闭分销
  292. if ($orderProduct['is_commission'] == StatusEnum::ENABLED) {
  293. $isCommission = true;
  294. }
  295. }
  296. // 退款进用户余额/原路退回
  297. if ($order->pay_type == PayTypeEnum::USER_MONEY) {
  298. Yii::$app->services->memberCreditsLog->incrMoney(new CreditsLogForm([
  299. 'member' => Yii::$app->services->member->findById($order->buyer_id),
  300. 'num' => $order->pay_money,
  301. 'group' => 'orderRefund',
  302. 'map_id' => $order->id,
  303. 'remark' => '订单退单-' . $order->order_sn,
  304. ]));
  305. } elseif (in_array($order->pay_type, array_keys(PayTypeEnum::thirdParty()))) {
  306. Yii::$app->services->extendPay->refund($order->pay_type, $order->pay_money, $order->order_sn);
  307. }
  308. $isCommission == true && Yii::$app->tinyDistributeService->promoterOrder->closeAll($order->order_sn, 'order', 'TinyShop');
  309. // 增加本身订单退款金额
  310. Order::updateAllCounters(['refund_money' => $order->pay_money], ['id' => $order->id]);
  311. // 关闭订单
  312. Yii::$app->tinyShopService->order->close($order->id);
  313. // 退单提醒用户
  314. Yii::$app->tinyShopService->notify->createRemindByReceiver(
  315. $order->id,
  316. SubscriptionActionEnum::ORDER_CANCEL,
  317. $order->buyer_id,
  318. ['order' => $order]
  319. );
  320. // 记录日志
  321. Yii::$app->services->actionLog->create('order', '退单', $id);
  322. $transaction->commit();
  323. return ResultHelper::json(200, '操作成功');
  324. } catch (\Exception $e) {
  325. $transaction->rollBack();
  326. return ResultHelper::json(422, $e->getMessage());
  327. }
  328. }
  329. /**
  330. * 伪删除
  331. *
  332. * @param $id
  333. * @return mixed
  334. */
  335. public function actionDestroy($id)
  336. {
  337. $model = $this->modelClass::findOne($id);
  338. // 非关闭订单不可删除
  339. if ($model->order_status != OrderStatusEnum::REPEAL) {
  340. return $this->message("删除失败", $this->redirect(['index']), 'error');
  341. }
  342. $model->status = StatusEnum::DELETE;
  343. if ($model->save()) {
  344. Yii::$app->services->actionLog->create('order', '删除订单', $id);
  345. return $this->message("删除成功", $this->redirect(['index']));
  346. }
  347. return $this->message("删除失败", $this->redirect(['index']), 'error');
  348. }
  349. /**
  350. * 打单标记
  351. *
  352. * @param $id
  353. * @param $status
  354. * @return array|mixed|string
  355. */
  356. public function actionPrintRecord($id, $status)
  357. {
  358. $this->modelClass::updateAll(['is_print' => $status], ['id' => $id]);
  359. return $this->message('操作成功', $this->redirect(Yii::$app->request->referrer));
  360. }
  361. /**
  362. * @param $id
  363. * @return array|mixed
  364. */
  365. public function actionPrintReceipt($id, $config_id)
  366. {
  367. if (!($model = $this->modelClass::findOne($id))) {
  368. return ResultHelper::json(422, '找不到订单');
  369. }
  370. try {
  371. Yii::$app->tinyShopService->order->printReceipt($model, $config_id);
  372. return ResultHelper::json(200, '打印成功');
  373. } catch (\Exception $e) {
  374. return ResultHelper::json(422, $e->getMessage());
  375. }
  376. }
  377. /**
  378. * Class print delivery
  379. * @param $id
  380. * @return mixed
  381. */
  382. public function actionPrintDelivery($id)
  383. {
  384. /** @var Order $model */
  385. $model = Order::find()
  386. ->where(['>=', 'status', StatusEnum::DISABLED])
  387. ->andWhere(['id' => $id])
  388. ->andFilterWhere(['merchant_id' => $this->getMerchantId()])
  389. ->with(['member', 'product', 'expressCompany'])
  390. ->one();
  391. $product = $model->product;
  392. $total = 0;
  393. $sku = [];
  394. foreach ($product as $key => $detail) {
  395. if (in_array($detail['refund_status'], RefundStatusEnum::deliver())) {
  396. $sku[$key] = Product::find()
  397. ->where(['id' => $detail['product_id']])
  398. ->with('cate')
  399. ->asArray()
  400. ->one();
  401. $sku[$key]['num'] = $detail['num'];
  402. $sku[$key]['sku_name'] = $detail['sku_name'];
  403. $sku[$key]['product_money'] = $detail['product_money'];
  404. $sku[$key]['refund_status'] = $detail['refund_status'];
  405. $total += $detail['num'];
  406. }
  407. }
  408. ArrayHelper::multisort($sku, ['tags'], [SORT_ASC]);
  409. return $this->render($this->action->id, [
  410. 'model' => $model,
  411. 'product' => $sku,
  412. 'total' => $total,
  413. 'productMoney' => $model->product_money - $model->refund_money,
  414. ]);
  415. }
  416. /**
  417. * @param $id
  418. * @return Order
  419. * @throws NotFoundHttpException
  420. */
  421. protected function findModel($id)
  422. {
  423. /* @var $model Order */
  424. if (empty($id) || empty($model = $this->modelClass::find()
  425. ->where(['id' => $id])
  426. ->andFilterWhere(['merchant_id' => $this->getMerchantId()])
  427. ->one())
  428. ) {
  429. throw new NotFoundHttpException('找不到订单');
  430. }
  431. return $model;
  432. }
  433. }
粤ICP备19079148号