CloudStockFillOrder.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. <?php
  2. namespace addons\CloudStock\common\models;
  3. use common\enums\PayTypeEnum;
  4. use common\enums\StatusEnum;
  5. use common\models\base\BaseActiveRecord;
  6. use common\models\common\PaymentTrade;
  7. use common\models\common\ScoreLog;
  8. use common\models\goods\Goods;
  9. use common\models\order\Order;
  10. use common\models\user\User;
  11. use common\components\export\CsvTool;
  12. use common\enums\DownloadEnum;
  13. use common\models\common\Download;
  14. use addons\CloudStock\common\enums\CloudStockEnum;
  15. use Exception;
  16. use Yii;
  17. /**
  18. * This is the model class for table "{{%addons_cloud_stock_fill_order".
  19. *
  20. * @property int $id
  21. * @property int $mall_id 商城id
  22. * @property int $user_id 补货代理商用户id
  23. * @property int $trade_id 支付流水记录 id
  24. * @property float $pay_money 支付金额
  25. * @property string $order_no 补货订单编号
  26. * @property string $trade_no 支付流水号
  27. * @property int $is_pay 是否支付
  28. * @property int $goods_id 商品id
  29. * @property int $num 补货商品数量
  30. * @property int $status 状态[-1:删除;0:禁用;1启用]
  31. * @property int $created_at
  32. * @property int $updated_at
  33. * @property int $payment_type
  34. * @property int $price_difference_order_id 价差礼包订单id
  35. * @property int $price_difference_order_detail_id 价差礼包订单详情id
  36. * @property int $batch_fill_order_id 批量补货订单id
  37. */
  38. class CloudStockFillOrder extends BaseActiveRecord
  39. {
  40. /**
  41. * {@inheritdoc}
  42. */
  43. public static function tableName()
  44. {
  45. return '{{%addons_cloud_stock_fill_order}}';
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function rules()
  51. {
  52. return [
  53. [['mall_id', 'user_id', 'order_no', 'goods_id'], 'required'],
  54. [['mall_id', 'user_id', 'trade_id', 'is_pay', 'goods_id', 'num', 'status', 'created_at', 'updated_at', 'payment_type',
  55. 'price_difference_order_id', 'price_difference_order_detail_id', 'batch_fill_order_id'], 'integer'],
  56. [['pay_money'], 'number'],
  57. [['order_no', 'trade_no'], 'string', 'max' => 255],
  58. ];
  59. }
  60. /**
  61. * {@inheritdoc}
  62. */
  63. public function attributeLabels()
  64. {
  65. return [
  66. 'id' => 'ID',
  67. 'mall_id' => '商城id',
  68. 'user_id' => '补货代理商用户id',
  69. 'trade_id' => '支付流水记录 id',
  70. 'pay_money' => '支付金额',
  71. 'order_no' => '补货订单编号',
  72. 'trade_no' => '支付流水号',
  73. 'is_pay' => '是否支付',
  74. 'goods_id' => '商品id',
  75. 'num' => '补货商品数量',
  76. 'status' => '状态[-1:删除;0:禁用;1启用]',
  77. 'created_at' => 'Created At',
  78. 'updated_at' => 'Updated At',
  79. 'payment_type' => '支付方式',
  80. 'batch_fill_order_id' => '批量补货订单ID',
  81. ];
  82. }
  83. public function getUser()
  84. {
  85. return $this->hasOne(User::class, ['id' => 'user_id'])->select(['id', 'nickname', 'avatar_url', 'mobile', 'parent_id']);
  86. }
  87. public function getTrade()
  88. {
  89. return $this->hasOne(Trande::class, ['id' => 'trade_id'])->select(['id', 'nickname', 'avatar_url', 'mobile']);
  90. }
  91. public function getScore()
  92. {
  93. return $this->hasOne(ScoreLog::class, ['source_table_id' => 'trade_id'])->select(['change_num']);
  94. }
  95. public function getGoods()
  96. {
  97. return $this->hasOne(Goods::class, ['id' => 'goods_id'])->select(['id', 'goods_name', 'cover_pic', 'price']);
  98. }
  99. public static function setData(int $mall_id, array $data)
  100. {
  101. if (!empty($data['id'])) {
  102. $model = self::findOne(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $data['id']]);
  103. if (empty($model)) {
  104. self::$static_error = '数据异常';
  105. return false;
  106. }
  107. } else {
  108. $model = new self();
  109. $model->loadDefaultValues();
  110. $model->mall_id = $mall_id;
  111. }
  112. foreach ($data as $key => $val) {
  113. $model->$key = $val;
  114. }
  115. // dd($model);
  116. if (!$model->save()) {
  117. self::$static_error = '保存数据失败:' . $model->getErrorMessage();
  118. return false;
  119. }
  120. return $model;
  121. }
  122. public static function check($params): bool
  123. {
  124. $order_no_arr = $params['order_no_arr'];
  125. $payment_order_list = $params['payment_order_list'];
  126. foreach($order_no_arr as $order_no){
  127. if(substr($order_no,0,3) == 'CSP'){
  128. $counts = CloudStockAgentOrder::find()->where(['order_no'=>$order_no_arr,'send_status'=>CloudStockEnum::PICK_ORDER_STATUS3])->count();
  129. }else{
  130. $counts = self::find()->where(['order_no'=>$order_no_arr,'is_pay'=>0])->count();
  131. }
  132. }
  133. if ($counts != count($payment_order_list)) {
  134. self::$static_error = '补货订单不一致';
  135. return false;
  136. }
  137. return true;
  138. }
  139. /**
  140. * 导出字段数组
  141. * @Author: hua
  142. * @DateTime: 2021/10/11 18:06
  143. * @Copyright: copyright (c) 2021 广东七件事集团
  144. * @return \string[][]
  145. */
  146. public static function fieldsLists($field = null){
  147. $fields = [
  148. 'id' => '订单ID',
  149. 'user_id' => '代理商用户id',
  150. 'nickname' => '代理商用户昵称',
  151. 'goods_name' => '商品名称',
  152. 'fill_parent' => '补货上级',
  153. 'num' => '补货数量',
  154. 'created_at' => '订单创建时间',
  155. 'order_no' => '订单编号',
  156. 'trade_no' => '支付流水号',
  157. 'pay_money' => '实际支付金额',
  158. 'payment_type' => '支付方式',
  159. 'is_pay' => '是否支付',
  160. ];
  161. if ($field === null) return $fields;
  162. $temp = [];
  163. foreach ($field as $val) {
  164. if (isset($fields[$val])) $temp[$val] = $fields[$val];
  165. }
  166. return $temp;
  167. }
  168. /**
  169. * 导出
  170. */
  171. public static function exportOrder(array $data) {
  172. $download_id = $data['download_id'] ?? 0;
  173. $download = Download::findOne(['id' => $download_id]);
  174. if ($download) {
  175. try {
  176. $params = json_decode($download->params, true);
  177. $filename = $download->name;
  178. $type = $download->type;
  179. $fields = isset($params['fields']) ? $params['fields'] : null;
  180. $exportField = self::fieldsLists($fields);
  181. $exportField = array_keys($exportField);
  182. $where[] = ['=', 'mall_id', $params['mall_id']];
  183. $where[] = ['in', 'status', [StatusEnum::DISABLED, StatusEnum::ENABLED]];
  184. $where[] = ['=', 'price_difference_order_id', 0]; // 只显示补货订单
  185. if (!empty($params['keyword'])) {
  186. $user_list = User::find()->where(['or',
  187. ['id' => $params['keyword']],
  188. ['mobile' => $params['keyword']],
  189. ['nickname' => $params['keyword']]])->select('id')->asArray()->all();
  190. $user_id_arr = array_column($user_list, 'id');
  191. $where[] = ['user_id' => $user_id_arr];
  192. }
  193. if (!empty($params['goods_name'])) {
  194. $goods_list = Goods::lists(['where' => [['like', 'goods_name', $params['goods_name']]]]);
  195. if ($goods_list) {
  196. $goods_id_arr = array_column($goods_list, 'id');
  197. $where[] = ['goods_id' => $goods_id_arr];
  198. }
  199. }
  200. if (isset($params['is_pay']) && is_numeric($params['is_pay'])) {
  201. $where[] = ['=', 'is_pay', $params['is_pay']];
  202. }
  203. if (!empty($params['payment_type'])) $where[] = ['=', 'payment_type', $params['payment_type'] ];
  204. if (!empty($params['start'])) $where[] = ['>=', 'created_at', strtotime($params['start'])];
  205. if (!empty($params['end'])) $where[] = ['<=', 'created_at', strtotime($params['end'])];
  206. if (!empty($params['id'])) {
  207. $where[] = ['=', 'id', $params['id']];
  208. }
  209. $wheres['order'] = 'id desc';
  210. $wheres['with'] = ['user', 'goods'];
  211. $wheres['where'] = $where;
  212. $model = self::find();
  213. self::paramPack($wheres, $model);
  214. $list = [];
  215. $exportheader = [];
  216. $isSetHeader = true;
  217. //所有团队部分修改
  218. $i = 1;
  219. $page_size = 1000;
  220. $payment_type_list= PayTypeEnum::getMap();
  221. while ($log_list = $model->asArray()->offset(($i - 1) * $page_size)->limit($page_size)->all()){
  222. if(in_array('payment_type',$fields)){
  223. $trade_nos = array_column($log_list,'trade_no');
  224. $payment_trade_arr = PaymentTrade::lists(['where'=>[['out_trade_no'=>$trade_nos]],'index'=>'out_trade_no','select'=>'out_trade_no,pay_type as payment_type']);
  225. $fill_order_ids = [];
  226. foreach ($log_list as $val){
  227. if(empty($val['trade_no'])){
  228. $fill_order_ids[]=$val['id'];
  229. }
  230. }
  231. if(!empty($fill_order_ids)){
  232. $fill_order_relations = CloudStockFillOrderRelation::lists(['where'=>[['fill_order_id'=>$fill_order_ids]],'index'=>'fill_order_id','select'=>'fill_order_id,order_id']);
  233. $order_ids = array_column($fill_order_relations,'order_id');
  234. $order_arr = Order::lists(['where'=>[['id'=>$order_ids]],'index'=>'id','select'=>'id,payment_type']);
  235. }
  236. }
  237. // 得到补货上级
  238. [
  239. 'deduction_user_id_arr' => $deduction_user_id_arr,
  240. 'user_list' => $user_list
  241. ] = self::getFillParentList($params['mall_id'], array_column($log_list, 'id'));
  242. foreach ($log_list as $l){
  243. $temp = [];
  244. //按顺序组装
  245. if(in_array('id', $fields)) {
  246. $temp['id'] = $l['id'];
  247. $isSetHeader && array_push($exportheader, '订单ID');
  248. }
  249. if(in_array('user_id', $fields)) {
  250. $temp['user_id'] = $l['user_id'];
  251. $isSetHeader && array_push($exportheader, '代理商用户id');
  252. }
  253. if(in_array('nickname', $fields)) {
  254. $temp['nickname'] = $l['user']['nickname'];
  255. $isSetHeader && array_push($exportheader, '代理商用户昵称');
  256. }
  257. if(in_array('goods_name', $fields)) {
  258. $temp['goods_name'] = $l['goods']['goods_name'];
  259. $isSetHeader && array_push($exportheader, '商品名称');
  260. }
  261. if(in_array('fill_parent', $fields)) { // 补货上级
  262. // 得到补货上级
  263. $fromUser = [];
  264. if (isset($deduction_user_id_arr[$l['id']])) {
  265. $deductionUserIds = array_unique($deduction_user_id_arr[$l['id']]);
  266. foreach ($deductionUserIds as $uid) {
  267. if (!isset($user_list[$uid])) {
  268. continue;
  269. }
  270. $fromUser[] = sprintf(
  271. '补货用户ID:"%s" 补货用户昵称:"%s"',
  272. $uid,
  273. $user_list[$uid]['nickname']
  274. );
  275. }
  276. }
  277. $temp['fill_parent'] = implode(' ,', $fromUser);
  278. $isSetHeader && array_push($exportheader, '补货上级');
  279. }
  280. if(in_array('num', $fields)) {
  281. $temp['num'] = $l['num'];
  282. $isSetHeader && array_push($exportheader, '补货数量');
  283. }
  284. if(in_array('created_at', $fields)) {
  285. $temp['created_at'] = date('Y-m-d H:i:s', $l['created_at']);
  286. $isSetHeader && array_push($exportheader, '订单创建时间');
  287. }
  288. if(in_array('order_no', $fields)) {
  289. $temp['order_no'] = $l['order_no'];
  290. $isSetHeader && array_push($exportheader, '订单编号');
  291. }
  292. if(in_array('trade_no', $fields)) {
  293. $temp['trade_no'] = $l['trade_no'];
  294. $isSetHeader && array_push($exportheader, '支付流水号');
  295. }
  296. if(in_array('pay_money', $fields)) {
  297. $temp['pay_money'] = $l['pay_money'];
  298. $isSetHeader && array_push($exportheader, '实际支付金额');
  299. }
  300. if(in_array('is_pay', $fields)) {
  301. if($l['is_pay'] == 1){
  302. $temp['is_pay'] = '已支付';
  303. }else{
  304. $temp['is_pay'] = '未支付';
  305. }
  306. $isSetHeader && array_push($exportheader, '是否已支付');
  307. }
  308. if(in_array('payment_type',$fields)){
  309. $isSetHeader && array_push($exportheader, '支付方式');
  310. if(!empty($l['trade_no'])){
  311. $payment_type = $payment_trade_arr[$l['trade_no']]['payment_type']??'';
  312. }else{
  313. if(isset($fill_order_relations)&&isset($fill_order_relations[$l['id']])){
  314. $order_id = $fill_order_relations[$l['id']]['order_id'];
  315. if(isset($order_arr)&&isset($order_arr[$order_id])){
  316. $payment_type = $order_arr[$order_id]['payment_type'];
  317. }
  318. }
  319. }
  320. $temp['payment_type'] = '';
  321. if(isset($payment_type)){
  322. $temp['payment_type']=$payment_type_list[$payment_type]??'';
  323. }
  324. }
  325. $list[] = $temp;
  326. $isSetHeader = false;
  327. }
  328. $i++;
  329. }
  330. if (!empty($list)) {
  331. $csv = new CsvTool();
  332. $csv->filename = $filename;
  333. $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type);
  334. $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC;
  335. $csv->header = $exportheader;
  336. $csv->data = $list;
  337. $csv->export();
  338. $csv->updateDown($download, $params['mall_id']);
  339. }
  340. }catch (\Exception $e) {
  341. $download->status = 3;
  342. $res = $download->save();
  343. var_dump($e->getMessage().$e->getFile().$e->getLine());
  344. self::setStaticError($e->getMessage());
  345. return $e->getMessage();
  346. }
  347. }
  348. }
  349. public function fixOrder(){
  350. $i = 1;
  351. $page_size = 1000;
  352. while ($list = CloudStockBuyingOrder::find()->where(['payment_type' => 0])
  353. ->offset(($i - 1) * $page_size)->limit($page_size)->all()) {
  354. $order_ids = array_column($list, 'order_id');
  355. $order_list = Order::lists([
  356. 'where' => [
  357. ['id' => $order_ids]
  358. ],
  359. 'index' => 'id'
  360. ]);
  361. foreach ($list as $buy_order) {
  362. if (isset($order_list[$buy_order['order_id']])) {
  363. $order = $order_list[$buy_order['order_id']];
  364. $buy_order->payment_type = $order['payment_type'];
  365. $res = $buy_order->save();
  366. var_dump($res);
  367. }
  368. }
  369. $i++;
  370. }
  371. $i = 1;
  372. $page_size = 1000;
  373. while ($list = CloudStockFillOrder::find()->where(['payment_type' => 0])
  374. ->offset(($i - 1) * $page_size)->limit($page_size)->all()) {
  375. $trade_ids = array_column($list, 'trade_id');
  376. $paymentTrade_list = \common\models\common\PaymentTrade::lists([
  377. 'where' => [
  378. ['id' => $trade_ids]
  379. ],
  380. 'index' => 'id'
  381. ]);
  382. foreach ($list as $fill_order) {
  383. if (isset($paymentTrade_list[$fill_order['trade_id']])) {
  384. $paymentTrade = $paymentTrade_list[$fill_order['trade_id']];
  385. $fill_order->payment_type = $paymentTrade['pay_type'];
  386. $res = $fill_order->save();
  387. var_dump($res);
  388. }
  389. }
  390. $i++;
  391. }
  392. }
  393. /**
  394. * 获取订单的补货上级
  395. *
  396. * @param int $mallId
  397. * @param array $order_id_arr
  398. *
  399. * @return array
  400. */
  401. private static function getFillParentList(int $mallId, array $order_id_arr)
  402. {
  403. $deduction_list = CloudStockDeductionDetail::lists([
  404. 'where' => [
  405. ['mall_id' => $mallId],
  406. ['order_id' => $order_id_arr],
  407. ['order_type' => CloudStockEnum::STOCK_ORDER_TYPE_REPLENISH],
  408. ['changes_type' => CloudStockEnum::CHANGE_TYPE_DEDUTION_FILL]
  409. ],
  410. 'select' => 'user_id,order_id',
  411. ]
  412. );
  413. $deduction_user_ids = array_column($deduction_list, 'user_id');
  414. $deduction_user_id_arr = [];
  415. foreach ($deduction_list as $val) {
  416. $deduction_user_id_arr[$val['order_id']][] = $val['user_id'];
  417. }
  418. $user_list = User::lists([
  419. 'where' => [
  420. ['id' => $deduction_user_ids]
  421. ],
  422. 'index' => 'id',
  423. 'select' => 'id,nickname,mobile,avatar_url',
  424. ]
  425. );
  426. $user_list[0] = [
  427. 'id' => 0,
  428. 'nickname' => '平台',
  429. 'mobile' => '',
  430. 'avatar_url' => '',
  431. ];
  432. return [
  433. 'deduction_user_id_arr' => $deduction_user_id_arr,
  434. 'user_list' => $user_list
  435. ];
  436. }
  437. public static function getOrderByNo($params) {
  438. try {
  439. $info = self::getOne([
  440. ['mall_id' => $params['mall_id']],
  441. ['order_no' => $params['order_no']]
  442. ], true, ['user', 'goods']);
  443. $data = [
  444. 'user' => $info['user'],
  445. 'pay_money' => $info['pay_money'],
  446. 'order_no' => $info['order_no'],
  447. 'id' => $info['id'],
  448. ];
  449. $data['product'][] = [
  450. 'pic_url' => $info['goods']['cover_pic'],
  451. 'goods_name' => $info['goods']['goods_name'],
  452. 'goods_attr_name' => '',
  453. 'price' => $info['goods']['price'],
  454. 'num' => $info['num'],
  455. ];
  456. return $data;
  457. } catch (\Exception $e) {
  458. throw new Exception($e->getMessage());
  459. }
  460. }
  461. }