StoreClerkLog.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. <?php
  2. namespace addons\Store\common\models;
  3. use addons\Clerk\common\models\ClerkLog;
  4. use addons\PlatformStoreClerk\common\models\PlatformStoreClerkGoodsSetting;
  5. use addons\PlatformStoreClerk\common\models\PlatformStoreClerkOrderDetail;
  6. use addons\Starfish\common\enums\StarfishEnum;
  7. use addons\Store\common\events\order\StoreSelfPickupOrderClerkEvent;
  8. use common\enums\AddonsEnum;
  9. use common\enums\ClerkEnum;
  10. use common\enums\MarketingTypeEnum;
  11. use common\enums\OrderStatusEnum;
  12. use common\enums\PayTypeEnum;
  13. use common\enums\RabbitMqEnum;
  14. use common\enums\ShippingStatusEnum;
  15. use common\enums\ShippingTypeEnum;
  16. use common\enums\StatusEnum;
  17. use common\globals\GlobalInvoke;
  18. use common\models\base\BaseActiveRecord;
  19. use common\models\goods\Goods;
  20. use common\models\mall\Mall;
  21. use common\models\mall\MallAddons;
  22. use common\models\order\Order;
  23. use common\models\order\OrderDetail;
  24. use common\models\order\OrderMarketing;
  25. use common\models\user\User;
  26. use services\common\UserWalletService;
  27. use addons\Store\addons\Verification\common\models\StoreVerificationCouponsClerkLog;
  28. use common\helpers\LockHelper;
  29. use Yii;
  30. /**
  31. * This is the model class for table "qimall_addons_store_clerk_log".
  32. *
  33. * @property int $id
  34. * @property int $mall_id
  35. * @property int $store_id 门店id
  36. * @property int $user_id 会员id
  37. * @property int $clerk_id 核销员id
  38. * @property string $mobile 电话
  39. * @property string $order_no 订单编号
  40. * @property int $status 状态[0禁用 1启用 -1删除]
  41. * @property int $created_at 创建时间
  42. * @property int $updated_at 修改时间
  43. */
  44. class StoreClerkLog extends BaseActiveRecord
  45. {
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public static function tableName()
  50. {
  51. return '{{%addons_store_clerk_log}}';
  52. }
  53. /**
  54. * {@inheritdoc}
  55. */
  56. public function rules()
  57. {
  58. return [
  59. [['mall_id', 'store_id', 'user_id', 'clerk_id', 'status', 'created_at', 'updated_at'], 'integer'],
  60. [['mobile'], 'string', 'max' => 11],
  61. [['order_no'], 'string', 'max' => 100],
  62. ];
  63. }
  64. /**
  65. * {@inheritdoc}
  66. */
  67. public function attributeLabels()
  68. {
  69. return [
  70. 'id' => 'ID',
  71. 'mall_id' => 'Mall ID',
  72. 'store_id' => '门店id',
  73. 'user_id' => '会员id',
  74. 'clerk_id' => '核销员id',
  75. 'mobile' => '电话',
  76. 'order_no' => '订单编号',
  77. 'status' => '状态[0禁用 1启用 -1删除]',
  78. 'created_at' => '创建时间',
  79. 'updated_at' => '修改时间',
  80. ];
  81. }
  82. public function getUser()
  83. {
  84. return $this->hasOne(User::class, ['id' => 'user_id']);
  85. }
  86. public function getOrder()
  87. {
  88. return $this->hasOne(StoreOrder::class, ['order_no' => 'order_no']);
  89. }
  90. public function getStoreClerk()
  91. {
  92. return $this->hasOne(StoreClerk::class, ['id' => 'clerk_id']);
  93. }
  94. public static function setData(array $params)
  95. {
  96. $clerk_code = (string)$params['clerk_code'];
  97. $clerk_code_pre = $clerk_code[0] . $clerk_code[1];
  98. if(strpos($params['clerk_code'],'PSC') !== false||$clerk_code_pre==ClerkEnum::PLATFORM_ORDER_BY_O2O_STORE_CLERK_CODE_PRE) {
  99. //平台订单通过门店核销员核销
  100. return self::clerkPlatformStoreOrderDetail($params);
  101. }
  102. if(strpos($params['clerk_code'],'HXQ') !== false||$clerk_code_pre==ClerkEnum::O2O_STORE_CLERK_COUPON_CODE_PRE) {
  103. //门店核销券通过门店核销员核销
  104. return self::clerkStoreVerification($params);
  105. }
  106. $t = Yii::$app->db->beginTransaction();
  107. try {
  108. $order = Order::findOne(['clerk_code'=> $params['clerk_code']]);
  109. if($order){
  110. $order->order_status = OrderStatusEnum::TAKE_FINISH;
  111. $order->sign_time = time();
  112. $res = $order->save();
  113. if($res==false) throw new \Exception($order->getErrorMessage());
  114. }
  115. $store_order = StoreOrder::getOne([['order_no' => $order['order_no']], ['mall_id' => $params['mall_id']], ['store_id' => $order['store_id']]]);
  116. if (empty($store_order)) throw new \Exception('订单不存在');
  117. if ($store_order->order_status != OrderStatusEnum::TAKE) throw new \Exception('该订单不是待自提');
  118. if ($store_order->order_status == OrderStatusEnum::TAKE_FINISH) throw new \Exception('已自提');
  119. if ($store_order->shipping_type != ShippingTypeEnum::PICKUP) throw new \Exception('该订单不是自提订单');
  120. $params['order_no'] = $store_order['order_no'];
  121. $params['user_id'] = $store_order['user_id'];
  122. $params['mobile'] = $store_order['mobile'];
  123. $model = new self();
  124. $model->loadDefaultValues();
  125. if (!$model->load($params, '')) throw new \Exception($model->getErrorMessage());
  126. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  127. $store_order->order_status = OrderStatusEnum::TAKE_FINISH;
  128. $store_order->sign_time = time();
  129. $store_order->save();
  130. // 维护累计核销金额及累计核销订单数
  131. $storeClerkFind = StoreClerk::find();
  132. StoreClerk::paramPack([
  133. 'where' => [['mall_id' => $params['mall_id']], ['user_id' => $params['user_id']], ['store_id' => $order['store_id']], ['status' => StatusEnum::ENABLED]],
  134. 'select' => 'id'
  135. ], $storeClerkFind);
  136. if ($storeClerkId = $storeClerkFind->scalar()) {
  137. $nums = OrderDetail::find()->where(['order_id'=>$order['id']])->sum('num');
  138. StoreClerk::incrNumsAndTotalMoney($storeClerkId, $nums, $store_order['pay_money']);
  139. }
  140. $t->commit();
  141. // 微信小程序发货
  142. $event = new StoreSelfPickupOrderClerkEvent($params['mall_id']);
  143. $data['id'] = $order['id'];
  144. Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  145. return $model;
  146. } catch (\Exception $e) {
  147. $t->rollBack();
  148. self::$static_error = $e->getMessage();
  149. return false;
  150. }
  151. }
  152. public static function clerkPlatformStoreOrderDetail($params)
  153. {
  154. try {
  155. $mall_id = $params['mall_id'];
  156. if (!MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_PLATFORM_STORE_CLERK)) {
  157. throw new \Exception('请安装门店核销员插件');
  158. }
  159. $clerk_detail = PlatformStoreClerkOrderDetail::getOrderByCode($mall_id, $params['clerk_code'],false);
  160. if (!$clerk_detail) throw new \Exception('该订单不存在');
  161. if ($clerk_detail->clerk_status !== 0) throw new \Exception('该订单已核销');
  162. // $rse = StoreClerk::getOne([['mall_id' => $mall_id], ['user_id' => $params['user_id']], ['status' => StatusEnum::ENABLED]],true);
  163. $clerk_list = StoreClerk::find()->where(['mall_id' => $mall_id,'user_id' => $params['user_id'],'status' => StatusEnum::ENABLED])->asArray()->all();
  164. if(!$clerk_list) throw new \Exception('你不是核销员');
  165. $clerk_store = array_column($clerk_list,null,'store_id');
  166. $clerk_store_ids = array_keys($clerk_store);
  167. //$store_id = $rse['store_id'];
  168. $goods_setting = PlatformStoreClerkGoodsSetting::getGoodsInfo($mall_id,$clerk_detail->goods_id);
  169. if(!$goods_setting) throw new \Exception('商品尚未关联该门店');
  170. $cate_id = $goods_setting['cate_id'];
  171. $is_bind_store = $goods_setting['is_bind_store'] ?? 0;
  172. $where = ['id' => $clerk_store_ids,'status' => StatusEnum::ENABLED];
  173. if($is_bind_store > 0 && $cate_id){
  174. $where['c_id'] = $cate_id;
  175. }
  176. $store_list = Store::find()->where($where)->select('id')->asArray()->all();
  177. if(!$store_list) throw new \Exception('商品尚未关联该门店');
  178. $store_id = $store_list[0]['id'];
  179. $clerk_user_id = $clerk_store[$store_id]['user_id'];
  180. //$store_ids = explode(',',$goods_setting['store_ids']);
  181. // $rse = StoreClerk::getOne([['mall_id' => $mall_id], ['user_id' => $params['user_id']], ['status' => StatusEnum::ENABLED],['store_id' => $store_ids]],true);
  182. //
  183. // if (empty($rse)) throw new \Exception('你不是核销员');
  184. // $store_id = $rse['store_id'];
  185. //
  186. // if(!in_array($store_id,$store_ids)) throw new \Exception('商品尚未关联该门店');
  187. //$order = Order::findOne(['id' => $clerk_detail->order_id]);
  188. //$order_detail = OrderDetail::findOne(['id' => $clerk_detail->order_detail_id]);
  189. //核销操作
  190. $clerk_detail->clerk_status = 1;
  191. $clerk_detail->clerk_time = time();
  192. $clerk_detail->clerk_store_id = $store_id;
  193. $clerk_detail->clerk_user_id = $clerk_user_id;
  194. $clerk_detail->save();
  195. if($clerk_detail->reward_num > 0){
  196. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, ['clerk_detail_id' => $clerk_detail->id,'store_id' => $store_id], PlatformStoreClerkOrderDetail::class, 'sendStoreReward');
  197. //发放核销奖励
  198. // $insert_wallet[] = [
  199. // 'mall_id' => $mall_id,
  200. // 'user_id' => $rse['user_id'],
  201. // 'is_frozen' => false,
  202. // 'wallet_type' => 'commission',
  203. // 'money' => $clerk_detail->reward_num,
  204. // 'desc' => '核销奖励',
  205. // 'source_table' => PlatformStoreClerkOrderDetail::tableName(),
  206. // 'source_table_id' => $clerk_detail->id,
  207. // 'from_type' => AddonsEnum::ADDONS_NAME_PLATFORM_STORE_CLERK,
  208. // 'capital_type' => 'store_clerk_order',
  209. // 'order_no' => $order['order_no'],
  210. // 'contributor_name' => $order_detail['goods_name']
  211. // ];
  212. //$res = UserWalletService::batchHandleByQueue($insert_wallet);
  213. //if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
  214. }
  215. $goods = Goods::findOne(['id'=>$clerk_detail->goods_id]);
  216. $store = Store::getOne([['id' => $store_id]], true, [], false, 'id,user_id,balance,logo_img,store_name');
  217. $order_detail = OrderDetail::findOne(['id'=>$clerk_detail['order_detail_id']]);
  218. $add_clerk_log_data = [
  219. 'mall_id' => $params['mall_id'],
  220. 'user_id' => $params['user_id'],
  221. 'mall_logo' => $store['logo_img']??'',
  222. 'mall_name' => $store['store_name']??'',
  223. 'name' => $goods['goods_name'],
  224. 'pic' => $order_detail['pic_url'],
  225. 'clerk_code' => (string)$params['clerk_code'],
  226. 'type' => ClerkEnum::PLATFORM_ORDER_BY_O2O_STORE_CLERK_CODE_PRE,
  227. 'extra' => json_encode([
  228. 'pay_money' => $order_detail['goods_price'],
  229. 'order_money' => $order_detail['goods_price'],
  230. 'clerk_nums' => $order_detail['num']??0,
  231. 'subtitle' => $goods['subtitle']??'',
  232. 'platform_store_clerk_order_detail_id' => $clerk_detail['id'],
  233. ]),
  234. ];
  235. $clerk_log_model = \common\models\common\ClerkLog::setData($add_clerk_log_data);
  236. if ($clerk_log_model == false) {
  237. throw new \Exception(\common\models\common\ClerkLog::getStaticError());
  238. }
  239. // 维护累计核销金额及累计核销订单数
  240. $storeClerkFind = StoreClerk::find();
  241. StoreClerk::paramPack([
  242. 'where' => [['mall_id' => $params['mall_id']], ['user_id' => $clerk_user_id], ['store_id' => $store_id], ['status' => StatusEnum::ENABLED]],
  243. 'select' => 'id'
  244. ], $storeClerkFind);
  245. if ($storeClerkId = $storeClerkFind->scalar()) {
  246. $nums = OrderDetail::find()->where(['order_id'=>$clerk_detail->order_id])->sum('num');
  247. $order = Order::findOne(['id' => $clerk_detail->order_id]);
  248. StoreClerk::incrNumsAndTotalMoney($storeClerkId, $nums, $order['pay_money'] ?? 0);
  249. }
  250. $event = new StoreSelfPickupOrderClerkEvent($params['mall_id']);
  251. $data['id'] = $clerk_detail['order_id'];
  252. Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  253. return true;
  254. } catch (\Exception $e) {
  255. self::$static_error = $e->getMessage();
  256. Yii::error('clerkPlatformStoreOrderDetail error:'.$e->getMessage().' File:'.$e->getFile().' Line:'.$e->getLine(), 'addons\Store\common\models\StoreClerkLog');
  257. return false;
  258. }
  259. }
  260. public static function getPlatformStoreOrderDetail($params)
  261. {
  262. $order_detail_id = $params['order_detail_id'];
  263. $select = 'id,mall_id,store_id,order_no,receiver_name,mobile,pay_money,shipping_money,original_goods_price,coupon_money,goods_price,order_status,pay_status,
  264. shipping_status,review_status,is_feedback,address,created_at,pay_time,region_name,remark,consign_time,finish_time,sign_time,shipping_type,payment_type,score,score_money,marketing_id,marketing_type,extra_info,order_source';
  265. $where = [];
  266. $where[] = ['mall_id' => $params['mall_id']];
  267. $where[] = ['id' => $params['order_id']];
  268. $order = Order::getOne($where, true, ['detail' => function ($query) use($order_detail_id) {
  269. $query->select('id,order_id,goods_id,goods_name,pic_url,num,price,is_feedback,sign_id,goods_attr_name,order_status,adjust_money,extra_info,goods_price')->where(['id' => $order_detail_id]);
  270. }], false, $select);
  271. if (empty($order) || $order['store_id'] > 0) {
  272. throw new \Exception('该订单不存在');
  273. }
  274. $rse = StoreClerk::getOne([['mall_id' => $params['mall_id']], ['user_id' => $params['user_id']], ['status' => StatusEnum::ENABLED]],true);
  275. if (empty($rse)){
  276. throw new \Exception('你不是核销员');
  277. }
  278. $goods_setting = PlatformStoreClerkGoodsSetting::getGoodsInfo($params['mall_id'],$params['goods_id']);
  279. if(!$goods_setting ) {
  280. throw new \Exception('商品尚未关联该门店');
  281. }
  282. $clerk_list = StoreClerk::find()->where(['mall_id' => $params['mall_id'],'user_id' => $params['user_id'],'status' => StatusEnum::ENABLED])->asArray()->all();
  283. if(!$clerk_list){
  284. throw new \Exception('你不是核销员');
  285. }
  286. $clerk_store = array_column($clerk_list,null,'store_id');
  287. $clerk_store_ids = array_keys($clerk_store);
  288. $cate_id = $goods_setting['cate_id'];
  289. $is_bind_store = $goods_setting['is_bind_store'] ?? 0;
  290. $where = ['id' => $clerk_store_ids,'status' => StatusEnum::ENABLED];
  291. if($is_bind_store > 0 && $cate_id){
  292. $where['c_id'] = $cate_id;
  293. }
  294. $store_list = Store::find()->where($where)->select('id')->asArray()->all();
  295. if(!$store_list) {
  296. throw new \Exception('商品尚未关联该门店');
  297. }
  298. $store_id = $store_list[0]['id'];
  299. $clerk_user_id = $clerk_store[$store_id]['user_id'];
  300. $marketing = OrderMarketing::getMarketingInfo($order);
  301. $order['order_status_text'] = OrderStatusEnum::getMap();
  302. $order['is_feedback_text'] = OrderStatusEnum::getFeedbackMap();
  303. $order['shipping_type_text'] = ShippingTypeEnum::getMap();
  304. $order['payment_type_text'] = PayTypeEnum::getMap();
  305. $order['pay_type_list'] = \Yii::$app->services->pay->getEnablePayment($params['mall_id'],$params['platform']);
  306. $adjust_money = array_sum(array_column($order['detail'], 'adjust_money'));//预留字段
  307. if ($adjust_money) {
  308. $order['change_price'] = $adjust_money;
  309. }
  310. $order['marketing'] = $marketing;
  311. $order['marketing_type_map'] = MarketingTypeEnum::getMap();
  312. $order_setting = Yii::$app->services->setting->mall->get($params['mall_id'], 'order');
  313. $order['payment_expire_time'] = $order_setting['payment_expire_time'] ?? 30;
  314. $order['auto_receiving_time'] = $order_setting['auto_receiving_time'] ?? 14;
  315. // 获取订单详情的状态文字描述
  316. $order['status_text'] = OrderStatusEnum::getApiStatus($order['status'], $order['shipping_type']);
  317. $order['status'] == OrderStatusEnum::NOT_PAY && $order['status_text']['desc'] = $order['payment_expire_time'] . $order['status_text']['desc'];
  318. $order['status'] == OrderStatusEnum::SHIPMENTS && $order['status_text']['desc'] = $order['auto_receiving_time'] . $order['status_text']['desc'];
  319. // 公共调用
  320. $order = GlobalInvoke::exec(GlobalInvoke::ORDER_DETAIL, $params['mall_id'], [
  321. 'order' => $order,
  322. 'mall_id' => $params['mall_id'],
  323. ]) ?: $order;
  324. $order['show_clerk_button'] = $order['order_status'] == OrderStatusEnum::TAKE ? 1:0;
  325. $order['clerk_code'] = $params['clerk_code'];
  326. $order['pay_money'] = $order['detail'][0]['goods_price'];
  327. return $order;
  328. }
  329. public static function clerkStoreVerification($params){
  330. try {
  331. $key = sprintf('StoreVerification:%s', $params['clerk_code']);
  332. if (LockHelper::fLock($key)) throw new \Exception('请勿频繁请求');
  333. StoreVerificationCouponsClerkLog::clerkStoreVerificationByClerkCode($params);
  334. LockHelper::unFLock($key);
  335. return true;
  336. } catch (\Exception $e) {
  337. LockHelper::unFLock($key);
  338. self::$static_error = $e->getMessage();
  339. return false;
  340. }
  341. }
  342. public static function clerkStoreVerificationByClerkCode($params){
  343. $key = sprintf('StoreVerification:%s', $params['mall_id'].$params['clerk_code']);
  344. try {
  345. if (LockHelper::fLock($key)) throw new \Exception('请勿频繁请求');
  346. StoreVerificationCouponsClerkLog::clerkStoreVerificationByClerkCode($params);
  347. LockHelper::unFLock($key);
  348. return true;
  349. } catch (\Exception $e) {
  350. LockHelper::unFLock($key);
  351. self::$static_error = $e->getMessage();
  352. return false;
  353. }
  354. }
  355. public static function updateOldData(){
  356. try {
  357. $i = 1;
  358. $page_size = 100;
  359. while (true) {
  360. $list = self::find()->where(['>', 'status', 0])
  361. ->offset(($i - 1) * $page_size)->limit($page_size)->all();
  362. if (empty($list)) {
  363. break;
  364. }
  365. $order_nos = array_column($list,'order_no');
  366. $clerk_ids = array_column($list,'clerk_id');
  367. $store_ids = array_column($list,'store_id');
  368. $store_clerk_list = StoreClerk::lists(['where'=>[['id'=>$clerk_ids]],'index'=>'id']);
  369. $store_list = Store::lists(['where'=>[['id'=>$store_ids]],'index'=>'id']);
  370. $order_list = Order::lists(['where'=>[['order_no'=>$order_nos]],'index'=>'order_no'],false);
  371. foreach ($list as $item){
  372. if(empty($order_list[$item['order_no']])||empty($store_clerk_list[$item['clerk_id']])||empty($store_list[$item['store_id']])) {
  373. continue;
  374. }
  375. $order = $order_list[$item['order_no']];
  376. if(\common\models\common\ClerkLog::findOne(['clerk_code'=>$order['clerk_code'],'type' => ClerkEnum::O2O_SELF_PICKUP_ORDERS_CLERK_CODE_PRE])) {
  377. continue;
  378. }
  379. $clerk_code = StoreOrder::getClerkCode($item['mall_id']);
  380. $store_clerk = $store_clerk_list[$item['clerk_id']];
  381. $store = $store_list[$item['store_id']];
  382. $order_detail = OrderDetail::find()->where(['order_id'=>$order['id']])->orderBy('id asc')->one();
  383. $nums = OrderDetail::find()->where(['order_id'=>$order['id']])->sum('num');
  384. $store_goods = StoreGoods::find()->where(['id'=>$order_detail['goods_id']])->one();
  385. StoreOrder::updateAll(['clerk_code'=>$clerk_code],['order_no'=>$item['order_no']]);
  386. $order->clerk_code = $clerk_code;
  387. $order->save();
  388. $add_clerk_log_data = [
  389. 'mall_id' => $order['mall_id'],
  390. 'user_id' => $store_clerk['user_id'],
  391. 'mall_logo' => $store['logo_img'],
  392. 'mall_name' => $store['store_name'],
  393. 'name' => $order_detail['goods_name'],
  394. 'pic' => $order_detail['pic_url'],
  395. 'clerk_code' => $clerk_code,
  396. 'type' => ClerkEnum::O2O_SELF_PICKUP_ORDERS_CLERK_CODE_PRE,
  397. 'extra' => json_encode([
  398. 'pay_money' => $order['pay_money'],
  399. 'order_money' => $order['pay_money'],
  400. 'clerk_nums' => $nums??0,
  401. 'subtitle' => $store_goods['subtitle']??'',
  402. 'order_id' => $order['id'] ?? 0,
  403. ]),
  404. ];
  405. $clerk_log_model = \common\models\common\ClerkLog::setData($add_clerk_log_data);
  406. var_dump($item['order_no']);
  407. }
  408. $i++;
  409. }
  410. }catch (\Exception $e){
  411. var_dump($e->getMessage().$e->getFile().$e->getLine());
  412. }
  413. }
  414. }