ReconciliationOrderForm.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  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\constants\OptionSetting;
  9. use app\librarys\Picqer\Barcode\BarcodeGeneratorJPG;
  10. use app\models\Admin;
  11. use app\models\AdminRole;
  12. use app\models\common\admin\order\CommonOrderSearch;
  13. use app\models\common\ExpressDetail;
  14. use app\models\DeliveryInfo;
  15. use app\models\Express;
  16. use app\models\FoodFlag;
  17. use app\models\Goods;
  18. use app\models\GoodsCat;
  19. use app\models\Md;
  20. use app\models\MdProfit;
  21. use app\models\Option;
  22. use app\models\Order;
  23. use app\models\OrderDetail;
  24. use app\models\OrderForm;
  25. use app\models\OrderRefund;
  26. use app\models\OrderStateFlow;
  27. use app\models\SaasUser;
  28. use app\models\Salesman;
  29. use app\models\Shop;
  30. use app\models\Store;
  31. use app\models\StoreCloud;
  32. use app\models\User;
  33. use app\models\CloudGoodsBind;
  34. use app\models\OrderTransit;
  35. use app\models\Supplier;
  36. use app\models\VerifyCardSale;
  37. use app\models\VerifyCard;
  38. use app\models\VerifyCardAccount;
  39. use app\utils\Delivery\Delivery;
  40. use app\utils\Export;
  41. use app\utils\ExportList;
  42. use app\utils\QrCode;
  43. use app\utils\ShareQrcode;
  44. use app\utils\Tools;
  45. use yii\base\Model;
  46. use yii\db\Query;
  47. use yii\helpers\Json;
  48. use \app\models\AlipayAcitvityVoucherOrder;
  49. use app\models\AuthRole;
  50. use app\models\DeliveryMaiyatian;
  51. use app\models\DeliveryKeloop;
  52. use app\models\Worker;
  53. use app\models\WorkerGoodsExt;
  54. use app\models\WorkerOrderExt;
  55. use app\models\BookingOrderExt;
  56. use yii\helpers\VarDumper;
  57. class ReconciliationOrderForm extends Model
  58. {
  59. public $filters_is_pay;
  60. public $filters_order_types;
  61. public $sort;
  62. public $sort_type;
  63. public $selected_rows;
  64. public $selected_row_keys;
  65. public $name;
  66. public $export;
  67. public $store_id;
  68. public $user_id;
  69. public $keyword;
  70. public $status;
  71. public $status_ext;
  72. public $worker_name;
  73. public $worker_tel;
  74. public $page;
  75. public $limit;
  76. public $activity_type;
  77. public $md_name;
  78. public $order_no;
  79. public $goods_name;
  80. public $mobile;
  81. public $mobiles;
  82. public $openids;
  83. public $book_name;
  84. public $book_mobile;
  85. public $is_offline;
  86. public $clerk_id;
  87. public $parent_id;
  88. public $shop_id;
  89. public $order_type;
  90. public $pay_type;
  91. public $dateStart;
  92. public $dateEnd;
  93. public $express_type;
  94. public $keywordType;
  95. public $seller_comments;
  96. public $fields;
  97. public $type;
  98. public $mch_id;
  99. public $flag; // 是否导出
  100. public $supplier_id;
  101. public $supplier;
  102. public $user_name;
  103. public $salesman_id;
  104. public $province_id;
  105. public $city_id;
  106. public $district_id;
  107. public $order_origin;
  108. public $send_time;
  109. public $booking_time_start;
  110. public $booking_time_end;
  111. public $worker_id;
  112. public $admin;
  113. public $admin_id;
  114. public $change_admin_id;
  115. public $confirm_payment;
  116. /**
  117. * @var 所属平台
  118. */
  119. public $platform; //所属平台
  120. /**
  121. * @var bool 是否是配送员订单
  122. */
  123. public $is_delivery = false; //是否是配送员订单
  124. /**
  125. * @var bool 是否是配送员订单
  126. */
  127. public $is_same_city = false; //是否是配送员订单
  128. /**
  129. * @var 获取默写城市的订单 例如:["\u5357\u5b81","\u4e0a\u6d77"]
  130. */
  131. public $shop_list;
  132. public $order_id;
  133. public $is_wastore;
  134. //麦芽田
  135. public $maiyatian;
  136. public $maiyatian_delivery_status;
  137. public $maiyatian_order_status;
  138. public $maiyatian_logistic_tag;
  139. public $cat_id = 0;
  140. //快跑者
  141. public $keloop;
  142. public $keloop_delivery_status;
  143. public function rules()
  144. {
  145. return [
  146. [['keyword', 'flag', 'selected_row_keys'], 'trim'],
  147. [['status', 'page', 'limit', 'user_id', 'is_offline', 'clerk_id', 'shop_id', 'keywordType', 'platform', 'order_type', 'pay_type', 'salesman_id', 'order_origin', 'admin_id', 'change_admin_id'], 'integer'],
  148. [['status',], 'default', 'value' => -1],
  149. [['page',], 'default', 'value' => 1],
  150. [['dateStart', 'dateEnd', 'express_type', 'md_name', 'order_no', 'goods_name', 'mobile'], 'trim'],
  151. [['seller_comments', 'flag', 'user_name', 'send_time',], 'string'],
  152. [['export', 'activity_type', 'mobiles', 'openids'], 'safe'],
  153. [['fields', 'is_delivery', 'shop_list', 'book_name', 'book_mobile', 'name'], 'safe'],
  154. [['maiyatian', 'maiyatian_delivery_status', 'maiyatian_order_status', 'maiyatian_logistic_tag', 'province_id', 'city_id', 'district_id'], 'safe'],
  155. [['keloop', 'keloop_delivery_status'], 'safe'],
  156. [['status_ext', 'worker_name', 'worker_tel'], 'safe'],
  157. [['booking_time_start', 'booking_time_end', 'worker_id', 'is_wastore'], 'safe'],
  158. ['cat_id', 'integer'],
  159. ['cat_id', 'default', 'value' => 0]
  160. ];
  161. }
  162. public function search()
  163. {
  164. if (!$this->validate()) {
  165. return [
  166. 'code' => 1,
  167. 'msg' => $this->getErrorSummary(false)[0],
  168. ];
  169. }
  170. $addSelect = [];
  171. $query = Order::find()->alias('o')->where(['!=', 'o.order_type', Order::ORDER_TYPE_Adopt]);
  172. $query->andWhere(['o.store_id' => $this->store_id]);
  173. if (!empty($this->selected_row_keys)) {
  174. $query->andWhere(['in', 'o.id', $this->selected_row_keys]);
  175. }
  176. if ($this->order_type == Order::ORDER_TYPE_WORKER) {
  177. $query->leftJoin(['woe' => WorkerOrderExt::tableName()], 'o.id = woe.order_id');
  178. $query->leftJoin(['w' => Worker::tableName()], 'w.id = woe.worker_id');
  179. if ($this->status_ext > -1) {
  180. $this->status = -1;
  181. $query->andWhere([
  182. 'woe.status_ext' => $this->status_ext,
  183. ]);
  184. }
  185. if ($this->worker_name) {
  186. $query->andWhere(['like', 'w.name', $this->worker_name]);
  187. }
  188. if ($this->worker_tel) {
  189. $query->andWhere(['like', 'w.tel', $this->worker_tel]);
  190. }
  191. } else {
  192. $query->andWhere(['!=', 'o.order_type', Order::ORDER_TYPE_WORKER]);
  193. }
  194. if ($this->order_type == 2) {
  195. $query->leftJoin(['boe' => BookingOrderExt::tableName()], 'o.id = boe.order_id');
  196. $addSelect = array_merge($addSelect, ['boe.worker_id', 'boe.worker_name', 'boe.status_ext', 'boe.time_sys_confirm', 'boe.user_revoke', 'boe.user_revoke_reason']);
  197. $addSelect = array_merge($addSelect, ['IF(boe.booking_time_end < "' . date('Y-m-d H:i:s') . '" AND boe.status_ext < ' . BookingOrderExt::STATUS_EXT_START . ', 1, 0) booking_time_out']);
  198. if ($this->booking_time_start) {
  199. $query->andWhere(['>=', 'boe.booking_time_end', $this->booking_time_start]);
  200. }
  201. if ($this->booking_time_end) {
  202. $query->andWhere(['<=', 'boe.booking_time_start', $this->booking_time_end]);
  203. }
  204. if (isset($this->worker_id)) {
  205. $query->andWhere(['boe.worker_id' => $this->worker_id]);
  206. }
  207. if ($this->status_ext == 500) {
  208. //已超时
  209. $query->andWhere(['and', ['<', 'boe.status_ext', BookingOrderExt::STATUS_EXT_START], ['<', 'boe.booking_time_end', date('Y-m-d H:i:s')]]);
  210. } else if ($this->status_ext == 600) {
  211. //未分配
  212. $query->andWhere(['boe.worker_id' => 0]);
  213. } else {
  214. isset($this->status_ext) && $this->status_ext > -1 && $query->andWhere(['boe.status_ext' => $this->status_ext]);
  215. }
  216. }
  217. if (get_md_id()) {
  218. $query->andWhere(['o.md_id' => get_md_id()]);
  219. }
  220. if (!empty($this->order_type) && in_array($this->order_type, [0, 1, 2, 3, Order::ORDER_TYPE_WORKER, Order::ORDER_TYPE_INTEGRAL])) {
  221. $query->andWhere([
  222. 'o.order_type' => $this->order_type
  223. ]);
  224. }
  225. if (!empty($this->pay_type) && in_array($this->pay_type, [0, 1, 2, 3, 4, 5, 6, 11])) {
  226. $query->andWhere([
  227. 'o.pay_type' => $this->pay_type
  228. ]);
  229. }
  230. $query->leftJoin(['u' => User::tableName()], 'u.id = o.user_id')
  231. ->leftJoin(['od' => OrderDetail::tableName()], 'od.order_id=o.id');
  232. switch ($this->status) {
  233. case 0:
  234. // 排除已取消的订单,未删除且未支付
  235. $query->andWhere(['<>', 'o.trade_status', Order::ORDER_FLOW_CANCEL])->andWhere(['o.is_delete' => Order::IS_DELETE_FALSE, 'o.is_pay' => Order::IS_PAY_FALSE]);
  236. break;
  237. case 1:
  238. // 未发货状态,未删除,已支付或货到付款
  239. $query->andWhere([
  240. 'o.trade_status' => Order::ORDER_FLOW_NO_SEND,
  241. 'o.is_delete' => Order::IS_DELETE_FALSE
  242. ])->andWhere(['or', ['o.is_pay' => Order::IS_PAY_TRUE], ['o.pay_type' => Order::PAY_TYPE_COD]]);
  243. break;
  244. case 2:
  245. // 已发货状态,未删除,已支付或货到付款
  246. $query->andWhere([
  247. 'o.trade_status' => Order::ORDER_FLOW_SEND,
  248. 'o.is_delete' => Order::IS_DELETE_FALSE
  249. ])->andWhere(['or', ['o.is_pay' => Order::IS_PAY_TRUE], ['o.pay_type' => Order::PAY_TYPE_COD]]);
  250. break;
  251. case 3:
  252. // 已确认状态,未删除,已支付或货到付款
  253. $query->andWhere([
  254. 'o.trade_status' => Order::ORDER_FLOW_CONFIRM,
  255. 'o.is_delete' => Order::IS_DELETE_FALSE
  256. ])->andWhere(['or', ['o.is_pay' => Order::IS_PAY_TRUE], ['o.pay_type' => Order::PAY_TYPE_COD]]);
  257. break;
  258. default:
  259. // 如果$order_id`为空,只过滤未删除的订单
  260. if (empty($this->order_id)) {
  261. $query->andWhere([
  262. 'o.is_delete' => Order::IS_DELETE_FALSE
  263. ]);
  264. }
  265. break;
  266. }
  267. if ($this->order_id && $this->order_id > 0) {
  268. $query->andWhere(['o.id' => $this->order_id]);
  269. }
  270. if (!$this->order_id) {
  271. if ($this->md_name) {
  272. $query->leftJoin(['md' => Md::tableName()], 'md.id=o.md_id')->andWhere(['like', 'md.name', $this->md_name]);
  273. }
  274. if ($this->order_no) {
  275. $query->andWhere(['like', 'o.order_no', $this->order_no]);
  276. }
  277. if ($this->mobile) {
  278. $query->andWhere([
  279. 'or',
  280. ['like', 'o.mobile', $this->mobile],
  281. ['like', 'u.binding', $this->mobile],
  282. ]);
  283. }
  284. if ($this->goods_name) {
  285. $query->andWhere(['like', 'od.goods_name', $this->goods_name]);
  286. }
  287. if ($this->user_name) {
  288. $query->andWhere(['like', 'u.nickname', $this->user_name]);
  289. }
  290. }
  291. if ($this->dateStart) {
  292. $query->andWhere(['>=', 'o.created_at', strtotime($this->dateStart)]);
  293. }
  294. if ($this->dateEnd) {
  295. $query->andWhere(['<=', 'o.created_at', strtotime($this->dateEnd)]);
  296. }
  297. if ($this->flag == Export::EXPORT) {
  298. $query_ex = clone $query;
  299. $list_ex = $query_ex;
  300. $export = new ExportList();
  301. $export->is_offline = $this->is_offline;
  302. $export->is_delivery = $this->is_delivery;
  303. $export->order_type = 0;
  304. $export->fields = $this->fields;
  305. $export->dataTransform_new($list_ex);
  306. }
  307. if ($this->platform !== null && $this->platform !== '') {
  308. $query->andWhere([
  309. 'u.platform' => $this->platform
  310. ]);
  311. }
  312. if (!empty($this->filters_is_pay)) {
  313. $query->andWhere(['o.is_pay' => $this->filters_is_pay]);
  314. }
  315. if (!empty($this->filters_order_types)) {
  316. foreach ($this->filters_order_types as $key => $value) {
  317. if ($value == 0) {
  318. $query->andWhere(['o.is_offline' => 0]);
  319. }
  320. if ($value == 1) {
  321. $query->andWhere(['o.is_offline' => 1]);
  322. }
  323. if ($value == 2) {
  324. $query->andWhere(['o.is_delivery' => 1]);
  325. }
  326. if ($value == 3) {
  327. $query->andWhere(['o.order_origin' => 4]);
  328. }
  329. }
  330. }
  331. $query->leftJoin(['a' => Admin::tableName()], 'a.id= o.admin_id ');
  332. $refundQuery1 = OrderRefund::find()->alias('or')
  333. ->select('or.status, or.order_id, or.created_at')
  334. ->where(['or.store_id' => $this->store_id, 'or.is_delete' => 0]);
  335. $refundQuery = (new Query())->from(['or' => $refundQuery1])->where('`or`.order_id=o.id')
  336. ->select('or.status')
  337. ->orderBy(['or.created_at' => SORT_DESC])
  338. ->limit(1);
  339. if ($this->mobiles || $this->openids) {
  340. if ($this->mobiles) {
  341. $_where = [
  342. 'or',
  343. ['o.mobile' => $this->mobiles],
  344. ['u.binding' => $this->mobiles],
  345. ];
  346. if ($this->openids) {
  347. $_where[] = [
  348. 'u.wechat_open_id' => $this->openids,
  349. ];
  350. }
  351. } else {
  352. $_where = [
  353. 'u.wechat_open_id' => $this->openids,
  354. ];
  355. }
  356. $query->andWhere($_where);
  357. }
  358. $query->orderBy('o.id DESC')
  359. ->select([
  360. 'o.*', 'u.nickname as de_name', 'u.platform', 'u.binding', 'u.avatar_url',
  361. 'refund' => $refundQuery, 'od.delivery_type', 'od.attr', 'o.name user_name', 'o.mobile user_mobile', 'o.address user_address', 'od.order_transit_id', 'a.name admin_name'
  362. ]);
  363. $query->addSelect($addSelect);
  364. $query->groupBy('o.id');
  365. if (!empty($this->sort) && !empty($this->sort_type)) {
  366. if ($this->sort_type == 'id') {
  367. $query->orderBy(['o.id' => $this->sort == 'asc' ? SORT_ASC : SORT_DESC,]);
  368. }
  369. if ($this->sort_type == 'sort') {
  370. $query->orderBy(['o.sort' => $this->sort == 'asc' ? SORT_ASC : SORT_DESC,]);
  371. }
  372. if ($this->sort_type == 'total_price') {
  373. $query->orderBy(['o.total_price' => $this->sort == 'asc' ? SORT_ASC : SORT_DESC,]);
  374. }
  375. if ($this->sort_type == 'pay_price') {
  376. $query->orderBy(['o.pay_price' => $this->sort == 'asc' ? SORT_ASC : SORT_DESC,]);
  377. }
  378. if ($this->sort_type == 'pay_datetime') {
  379. $query->orderBy(['o.pay_time' => $this->sort == 'asc' ? SORT_ASC : SORT_DESC,]);
  380. }
  381. } else {
  382. $query->orderBy(['o.id' => SORT_DESC]);
  383. }
  384. $sumQuery = clone $query;
  385. $sumPayPrice = $sumQuery->sum('pay_price');
  386. $sumDailyQuery = clone $query;
  387. $sumDailyQuery->andWhere([
  388. 'and',
  389. ['>=', 'o.created_at', strtotime(date('Y-m-d 00:00:00'))],
  390. ['<=', 'o.created_at', strtotime(date('Y-m-d 23:59:59'))],
  391. ]);
  392. $sumDaily = $sumDailyQuery->sum('pay_price');
  393. $pagination = pagination_make($query);
  394. $listArray = $pagination['list'];
  395. foreach ($listArray as $i => &$item) {
  396. if ($item['order_origin'] == 4) {
  397. $item['order_types'] = 3;
  398. } else if ($item['is_delivery'] == 1) {
  399. $item['order_types'] = 2;
  400. } else if ($item['is_offline'] == 1) {
  401. $item['order_types'] = 1;
  402. } else if ($item['is_offline'] == 0) {
  403. $item['order_types'] = 0;
  404. }
  405. $item['pay_datetime'] = date('Y-m-d H:i:s', $item['created_at']);;
  406. $item['goods_list'] = $this->getOrderGoodsList($item['id']);
  407. $item['avatar'] = '';
  408. if (empty($item['binding'])) {
  409. $item['nickname'] = $item['de_name'];
  410. $item['avatar'] = $item['avatar_url'];
  411. } else {
  412. $sass_user = SaasUser::findOne(['mobile' => $item['binding']]);
  413. if ($sass_user) {
  414. $item['nickname'] = $sass_user->name;
  415. $item['avatar'] = $sass_user->avatar;
  416. }
  417. }
  418. if ($item['order_type'] == 2) {
  419. $tmp_attr = Json::decode($item['attr']);
  420. $item['book']['date'] = $tmp_attr['date'] . ' ' . $tmp_attr['time'];
  421. }
  422. $rmList = [];
  423. if ($this->order_id && $this->order_id > 0) {
  424. $rmQuery = \app\models\OrderRefundMoney::find()->where(['is_delete' => 0, 'order_id' => $this->order_id]);
  425. $rmList = $rmQuery->orderBy('id DESC')->asArray()->all();
  426. foreach ($rmList as &$k) {
  427. $k['created_at'] = date('Y-m-d H:i:s', $k['created_at']);
  428. }
  429. }
  430. $item['rmList'] = $rmList;
  431. if (!empty($item['food_flag_id'])) {
  432. $food_flag = FoodFlag::findOne($item['food_flag_id']);
  433. $item['food_table_num'] = $food_flag->table_num;
  434. }
  435. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  436. $item['arrival_time_text'] = date('Y-m-d H:i:s', $item['arrival_time']);
  437. $item['goods_list'] = $this->getOrderGoodsList($item['id']);
  438. $item['clerk_name'] = '';
  439. $shop = Shop::findOne($item['shop_id']);
  440. if ($shop) {
  441. $user = User::findOne(Shop::findOne($item['shop_id'])->user_id);
  442. if ($user) {
  443. $item['clerk_name'] = $user->nickname;
  444. }
  445. }
  446. $item['integral'] = json_decode($item['integral'], true);
  447. if (isset($item['address_data'])) {
  448. $item['address_data'] = json_decode($item['address_data']);
  449. }
  450. $item['flag'] = 0;
  451. $item['delivery_info'] = [];
  452. // 同城配送配送信息
  453. if ($item['delivery_type'] == OrderDetail::GOODS_DELIVERY_IM) {
  454. $delivery_info = DeliveryInfo::findOne(['order_no' => $item['order_no']]);
  455. $item['delivery_info'] = [
  456. 'waybill_id' => $delivery_info->waybill_id,
  457. 'status' => Delivery::$validOrderStatus[$delivery_info->status],
  458. 'reason' => $delivery_info->reason_id > 0 ? Delivery::$validReason[$delivery_info->reason_id] : '',
  459. 'fee' => $delivery_info->fee,
  460. 'duct_fee' => $delivery_info->deduct_fee,
  461. 'delivery_type' => Delivery::$deliveryType[$delivery_info->delivery_type],
  462. 'rider_name' => $delivery_info->rider_name,
  463. 'rider_mobile' => $delivery_info->rider_mobile
  464. ];
  465. }
  466. if ($item['delivery_info']) {
  467. $item['pay_price'] > 0 && $item['express_price'] += $item['delivery_info']['fee'];
  468. }
  469. $item['md_info'] = null;
  470. if ($item['md_id']) {
  471. $item['md_info'] = Md::find()->where(['id' => $item['md_id']])
  472. ->select('id, name, address, cover_url, start_time, end_time, mobile, open_status, shop_time_type, is_single')->one();
  473. }
  474. $item['pay_user_info'] = null;
  475. if ($item['pay_user_id'] > 0) {
  476. $pay_saas_user = SaasUser::findOne(['mobile' => User::findOne($item['pay_user_id'])->binding]);
  477. $item['pay_user_info'] = [
  478. 'name' => $pay_saas_user->name,
  479. 'mobile' => $pay_saas_user->mobile
  480. ];
  481. }
  482. $item['all_discount'] = sprintf("%.2f", ($item['integral']['forehead'] + $item['coupon_sub_price']));
  483. $item['alipay_activity_voucher'] = AlipayAcitvityVoucherOrder::getByOrder($item['alipay_trade_no']);
  484. if ($item['store_id']) {
  485. // 增加查询商城的联系电话
  486. $item['store'] = Store::find()->where(['id' => $item['store_id']])->select('id, name, province_id, city_id, district_id, address,contact_tel')->one();
  487. }
  488. $diy_shop_name = Option::get(OptionSetting::DIY_SHOP_NAME, $item['store_id'], 'store', '自提配送')['value'] ?: '自提配送';
  489. $diy_shop_name = Option::get(OptionSetting::DIY_SHOP_NAME, $item['store_id'], 'pay', $diy_shop_name)['value'];
  490. $diy_express_name = Option::get(OptionSetting::DIY_EXPRESS_NAME, $item['store_id'], 'store', '快递配送')['value'] ?: '快递配送';
  491. $diy_express_name = Option::get(OptionSetting::DIY_EXPRESS_NAME, $item['store_id'], 'pay', $diy_express_name)['value'];
  492. $diy_delivery_name = Option::get(OptionSetting::DIY_DELIVERY_NAME, $item['store_id'], 'store', '同城配送')['value'] ?: '同城配送';
  493. $diy_delivery_name = Option::get(OptionSetting::DIY_DELIVERY_NAME, $item['store_id'], 'pay', $diy_delivery_name)['value'];
  494. $item['diy_express_name'] = intval($item['is_offline']) === 1 ? $diy_shop_name : (intval($item['is_delivery']) === 1 ? $diy_delivery_name : $diy_express_name);
  495. if (empty($item['address']) && (int)$item['is_offline']) {
  496. if (!empty($item['store'])) {
  497. $item['address'] = '配送到门店:' . $item['store']['name'];
  498. }
  499. if (!empty($item['md_info'])) {
  500. $item['address'] = '配送到门店:' . $item['md_info']['name'];
  501. }
  502. }
  503. $integral = 0;
  504. if ((int)$item['is_pay'] !== 0) {
  505. foreach ($item['goods_list'] as $goodskey => &$goods) {
  506. if ($goods['goods_id'] && $goods['attr']) {
  507. $cards = Goods::find()->where(['id' => $goods['goods_id']])->select('verify_card_id, integral')->one();
  508. if (!empty($cards->integral)) {
  509. $goods_integral = json_decode($cards->integral, true);
  510. $integral += (int)$goods_integral['give'];
  511. }
  512. $cloudGoodsInfo = CloudGoodsBind::find()->where(['goods_id' => $goods['goods_id'], 'is_delete' => 0])->one();
  513. if ($cloudGoodsInfo && isset($cloudGoodsInfo['cloud_goods_id'])) {
  514. $cloudInfo = [];
  515. $cloudInfo['cloud_goods_id'] = $cloudGoodsInfo['cloud_goods_id'];
  516. $cloudInfo['cloud_attr_id'] = $cloudGoodsInfo['cloud_attr_id'];
  517. $cloudInfo['cloud_supplier_id'] = $cloudGoodsInfo['cloud_supplier_id'];
  518. if ($cloudGoodsInfo['cloud_supplier_id'] > 0) {
  519. $supplierInfo = Supplier::find()->select('name,logo')->where(['cloud_supplier_id' => $cloudGoodsInfo['cloud_supplier_id'], 'is_delete' => 0])->one();
  520. if ($supplierInfo && $supplierInfo['name'] && $supplierInfo['logo']) {
  521. $cloudInfo['cloud_supplier_name'] = $supplierInfo['name'];
  522. $cloudInfo['cloud_supplier_logo'] = $supplierInfo['logo'];
  523. }
  524. }
  525. $listArray[$i]['goods_list'][$goodskey]['cloud_bind'] = json_encode($cloudInfo);
  526. $listArray[$i]['is_cloud_bind'] = (int)$item['trade_status'] === 0;
  527. }
  528. }
  529. }
  530. $item['integral'] = $integral;
  531. }
  532. if ($item['order_type'] == Order::ORDER_TYPE_WORKER) {
  533. $woe = WorkerOrderExt::findOne(['order_id' => $item['id']]);
  534. $item['woe'] = $woe;
  535. $item['w'] = $woe ? Worker::findOne($woe['worker_id']) : null;
  536. foreach ($item['goods_list'] as &$good) {
  537. $wge = WorkerGoodsExt::findOne(['goods_id' => $good['goods_id']]);
  538. $good['wge'] = $wge;
  539. }
  540. }
  541. if ($item['pt_order_id']) {
  542. $pt = \app\models\PtActivityOrder::findOne($item['pt_order_id']);
  543. if ($pt->pt_number) {
  544. $item['pt_order_id'] = $pt->pt_number;
  545. }
  546. }
  547. if ($item['confirm_time'] && !$item['send_time']) {
  548. $item['send_time'] = $item['confirm_time'];
  549. }
  550. }
  551. $adminPermission = AdminRole::find()->alias('ar')
  552. ->leftJoin(['ad' => AuthRole::tableName()], 'ad.id=ar.role_id')
  553. ->select(['ad.edit_data', 'ar.admin_id'])
  554. ->asArray()
  555. ->all();
  556. $has_admin = false;
  557. foreach ($adminPermission as $permission) {
  558. $data = json_decode($permission['edit_data'], true);
  559. if (in_array('PaymentStatement', (array)$data)) {
  560. $admins = Admin::find()
  561. ->where([
  562. 'or',
  563. ['id' => $permission['admin_id']],
  564. ['and', ['type' => ['admin', 'staff']], ['is_delete' => 0]]
  565. ])
  566. ->all();
  567. foreach ($admins as $admin) {
  568. if ($admin->id == $this->admin->id) {
  569. $has_admin = true;
  570. break;
  571. }
  572. }
  573. }
  574. }
  575. // 获取可导出数据
  576. $f = new ExportList();
  577. $exportList = $f->getList();
  578. if ($this->export) {
  579. return $this->export($listArray);
  580. }
  581. return [
  582. 'code' => 0,
  583. 'msg' => 'success',
  584. 'data' => [
  585. 'q' => $query->createCommand()->getRawSql(),
  586. 'totalSum' => $sumPayPrice,
  587. 'has_admin' => $has_admin,
  588. 'admins' => $admins ?? [],
  589. 'admin' => $this->admin,
  590. 'sumDaily' => $sumDaily,
  591. 'export_list' => $exportList,
  592. 'data' => $listArray,
  593. 'pageNo' => $pagination['pageNo'],
  594. 'pageSize' => $pagination['pageSize'],
  595. 'totalCount' => $pagination['totalCount'],
  596. 'print_setting' => Option::getPrintOrderSetting()
  597. ],
  598. ];
  599. }
  600. private function export($list)
  601. {
  602. $rows = [[
  603. 'ID',
  604. '排单',
  605. '会员信息',
  606. '订单号',
  607. '订单状态',
  608. '总金额(元)',
  609. '运费',
  610. '实际支付(元)',
  611. '是否已付款',
  612. '收货人',
  613. '收货人电话',
  614. '收货人地址',
  615. '下单门店',
  616. '商品',
  617. '规格',
  618. '数量',
  619. '成本价',
  620. '售价',
  621. '供货商信息',
  622. '备注',
  623. '时间',
  624. ]];
  625. usort($list, function ($a, $b) {
  626. if ($a['sort'] == 0 && $b['sort'] == 0) {
  627. return 0;
  628. }
  629. if ($a['sort'] == 0) {
  630. return 1;
  631. }
  632. if ($b['sort'] == 0) {
  633. return -1;
  634. }
  635. return $a['sort'] <=> $b['sort'];
  636. });
  637. foreach ($list as $item) {
  638. $tradStatus = '';
  639. if ($item['order_type'] == 1) {
  640. if (in_array($item['trade_status'], [0, 2])) {
  641. $tradStatus = '待使用';
  642. }
  643. }
  644. if ($item['trade_status'] == 1) {
  645. $tradStatus = '已取消';
  646. }
  647. if ($item['is_pay'] == 0) {
  648. $tradStatus = '未支付';
  649. }
  650. if ($item['is_pay'] == 1 && $item['trade_status'] == 0) {
  651. $tradStatus = '待发货';
  652. }
  653. if ($item['is_pay'] == 1 && $item['trade_status'] == 2) {
  654. $tradStatus = '待收货';
  655. }
  656. if ($item['is_pay'] == 1 && $item['trade_status'] == 3) {
  657. $tradStatus = '已完成';
  658. }
  659. $goods = [];
  660. $supplier_info = '';
  661. $cost_price = 0;
  662. foreach ($item['goods_list'] as $i => $gitem) {
  663. $goods_info = json_decode($gitem['goods_info'], true);
  664. $goods_info || $goods_info = Goods::findOne($gitem['goods_id']);
  665. $supplier = Supplier::findOne(['cloud_supplier_id' => $goods_info['cloud_supplier_id']]);
  666. $supplier_info = $supplier->supplier_name;
  667. $attr = [];
  668. $order_attr = array_column($gitem['attr_list'], 'attr_id');
  669. sort($order_attr);
  670. $goods_attr = json_decode($goods_info['attr'], true);
  671. $attr_cost_price = '0.00';
  672. $attr_goods_price = '0.00';
  673. foreach ($goods_attr as $value) {
  674. $goods_attr_id = array_column($value['attr_list'], 'attr_id');
  675. sort($goods_attr_id);
  676. if (!array_diff($goods_attr_id, $order_attr)) {
  677. $attr_cost_price = $value['cost_price'] ?? $value['price'];
  678. $attr_goods_price = $value['price'] ?: 0.00;
  679. }
  680. }
  681. $attr_cost_price = $attr_cost_price <= 0 ? '暂无数据' : sprintf('%.2f', $attr_cost_price);
  682. $attr_goods_price = $attr_goods_price <= 0 ? '暂无数据' : sprintf('%.2f', $attr_goods_price);
  683. $cost_price = sprintf('%.2f', (doubleval($cost_price) + doubleval($attr_cost_price)));
  684. foreach ($gitem['attr_list'] as $atitem) {
  685. $attr[] = isset($atitem['attr_name']) ? $atitem['attr_name'] . isset($atitem['cost_price']) : '';
  686. }
  687. $goods[] = $gitem['name'] . '(' . implode(',', $attr) . ')' . '(' . $gitem['num'] . $gitem['unit'] . ')' . '(' . $gitem['total_price'] . '元)(成本价:' . $attr_cost_price . ')';
  688. $dateString = date('Y-m-d H:i:s', $item['created_at']);
  689. if ($i == 0) {
  690. $r = [
  691. $item['id'],
  692. $item['sort'],
  693. $item['nickname'],
  694. $item['order_no'],
  695. $tradStatus,
  696. $item['total_price'],
  697. $item['express_price'],
  698. $item['pay_price'],
  699. $item['is_pay'] ? '已付款' : '未付款',
  700. $item['name'],
  701. $item['mobile'],
  702. $item['address'],
  703. (($item['md_info'] && $item['md_info']['name']) ? $item['md_info']['name'] : '') . '-' . $item['store']['name'],
  704. $gitem['name'],
  705. implode(',', $attr),
  706. $gitem['num'] . $gitem['unit'],
  707. $attr_cost_price,
  708. $attr_goods_price,
  709. $supplier_info,
  710. $item['shop_remark'],
  711. $item['created_at'],
  712. ];
  713. $rows[] = $r;
  714. } else {
  715. $r = [
  716. '',
  717. '',
  718. '',
  719. '',
  720. '',
  721. '',
  722. '',
  723. '',
  724. '',
  725. '',
  726. '',
  727. '',
  728. '',
  729. '',
  730. '',
  731. '',
  732. $gitem['name'],
  733. implode(',', $attr),
  734. $gitem['num'] . $gitem['unit'],
  735. $attr_cost_price,
  736. $attr_goods_price,
  737. $supplier_info,
  738. '',
  739. ];
  740. $rows[] = $r;
  741. }
  742. }
  743. }
  744. $writer = \Spatie\SimpleExcel\SimpleExcelWriter::streamDownload(time() . '.xlsx')->noHeaderRow()
  745. ->addRows($rows)->toBrowser();
  746. }
  747. public function getOrderGoodsList($order_id)
  748. {
  749. $orderDetailList = OrderDetail::find()->alias('od')
  750. ->leftJoin(['g' => Goods::tableName()], 'od.goods_id = g.id')
  751. ->where([
  752. 'od.is_delete' => 0,
  753. 'od.order_id' => $order_id,
  754. ])->select(['od.num', 'od.total_price', 'g.goods_no', 'od.attr', 'od.food_ext_goods', 'od.is_level', 'od.batch_price_tips', 'name' => 'od.goods_name', 'od.pic', 'od.goods_info', 'od.delivery_type', 'od.shop_id', 'od.goods_id', 'g.attr attrs'])->asArray()->all();
  755. foreach ($orderDetailList as &$item) {
  756. $item['form'] = OrderForm::findAll(['goods_id' => $item['goods_id'], 'order_id' => $order_id]);
  757. $item['food_ext_goods'] = (array)json_decode($item['food_ext_goods'], true);
  758. $item['attr_list'] = json_decode($item['attr'], true);
  759. $item['unit'] = Json::decode($item['goods_info'])['unit'];
  760. $item['price'] = sprintf('%.2f', ($item['total_price'] / $item['num']));
  761. $oattr = json_decode($item['attr'], true);
  762. $oattrIds = array_column($oattr, 'attr_id');
  763. sort($oattrIds);
  764. $gattr = json_decode($item['goods_info'], true)['attr'];
  765. $gattr = json_decode($gattr, true);
  766. $goods_no = '';
  767. foreach ($gattr as $igattr) {
  768. $attrIds = array_column($igattr['attr_list'], 'attr_id');
  769. sort($attrIds);
  770. if (implode('_', $attrIds) === implode('_', $oattrIds)) {
  771. $goods_no = $igattr['no'];
  772. }
  773. }
  774. $item['goods_no'] = trim($goods_no ?: $item['goods_no']);
  775. $item['code_path'] = '';
  776. if ($item['goods_no']) {
  777. $generator = new BarcodeGeneratorJPG();
  778. $barcode = $generator->getBarcode($item['goods_no'], $generator::TYPE_CODE_128, 2, 30);
  779. $filename = md5('goods_no_' . $item['goods_no']);
  780. $code_path = \Yii::$app->runtimePath . '/image/' . $filename . '.jpg';
  781. $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/runtime/image/' . $filename . '.jpg');
  782. file_put_contents($code_path, $barcode);
  783. $item['code_path'] = $pic_url;
  784. }
  785. $item['shop'] = [];
  786. if ($item['delivery_type'] == OrderDetail::GOODS_DELIVERY_SHOP) {
  787. $shop_info = Shop::find()->where(['id' => $item['shop_id']])->asArray()->one();
  788. if (!$shop_info) continue;
  789. $item['shop']['address'] = $shop_info['address'];
  790. $item['shop']['id'] = $shop_info['id'];
  791. $item['shop']['name'] = $shop_info['name'];
  792. $item['shop']['mobile'] = $shop_info['mobile'];
  793. }
  794. }
  795. return $orderDetailList;
  796. }
  797. public function confirmPayment()
  798. {
  799. if (!empty($this->confirm_payment) && !empty($this->change_admin_id)) {
  800. Order::updateAll(['confirm_payment' => 1, 'is_pay' => 1, 'admin_id' => $this->change_admin_id], ['id' => $this->confirm_payment]);
  801. }
  802. $admin = Admin::findOne($this->change_admin_id);
  803. return [
  804. 'code' => 0,
  805. 'msg' => 'success',
  806. 'data' => [
  807. 'admin_name' => $admin->name
  808. ],
  809. ];
  810. }
  811. }