HappinessClerkLog.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. <?php
  2. namespace addons\Happiness\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\events\order\OrderFinishEvent;
  29. use common\helpers\LockHelper;
  30. use Exception;
  31. use Yii;
  32. /**
  33. * This is the model class for table "qimall_addons_store_clerk_log".
  34. *
  35. * @property int $id
  36. * @property int $mall_id
  37. * @property int $store_id 门店id
  38. * @property int $user_id 会员id
  39. * @property int $clerk_id 核销员id
  40. * @property string $mobile 电话
  41. * @property string $order_no 订单编号
  42. * @property int $status 状态[0禁用 1启用 -1删除]
  43. * @property int $created_at 创建时间
  44. * @property int $updated_at 修改时间
  45. */
  46. class HappinessClerkLog extends BaseActiveRecord
  47. {
  48. /**
  49. * {@inheritdoc}
  50. */
  51. public static function tableName()
  52. {
  53. return '{{%addons_happiness_store_clerk_log}}';
  54. }
  55. /**
  56. * {@inheritdoc}
  57. */
  58. public function rules()
  59. {
  60. return [
  61. [['mall_id', 'store_id', 'user_id', 'clerk_id', 'status', 'created_at', 'updated_at'], 'integer'],
  62. [['mobile'], 'string', 'max' => 11],
  63. [['order_no'], 'string', 'max' => 100],
  64. ];
  65. }
  66. /**
  67. * {@inheritdoc}
  68. */
  69. public function attributeLabels()
  70. {
  71. return [
  72. 'id' => 'ID',
  73. 'mall_id' => 'Mall ID',
  74. 'store_id' => '门店id',
  75. 'user_id' => '会员id',
  76. 'clerk_id' => '核销员id',
  77. 'mobile' => '电话',
  78. 'order_no' => '订单编号',
  79. 'status' => '状态[0禁用 1启用 -1删除]',
  80. 'created_at' => '创建时间',
  81. 'updated_at' => '修改时间',
  82. ];
  83. }
  84. public function getUser()
  85. {
  86. return $this->hasOne(User::class, ['id' => 'user_id']);
  87. }
  88. public function getOrder()
  89. {
  90. return $this->hasOne(Order::class, ['order_no' => 'order_no']);
  91. }
  92. public function getDetail()
  93. {
  94. return $this->hasMany(OrderDetail::class, ['order_id' => 'id'])->via('order')->asArray();
  95. }
  96. public function getStoreClerk()
  97. {
  98. return $this->hasOne(HappinessClerk::class, ['id' => 'clerk_id']);
  99. }
  100. public function getClerkUser()
  101. {
  102. return $this->hasOne(User::class, ['id' => 'user_id'])->via('storeClerk');
  103. }
  104. public function getStore()
  105. {
  106. return $this->hasOne(HappinessStore::class, ['id' => 'store_id']);
  107. }
  108. public static function setData(array $params)
  109. {
  110. $clerk_code = (string)$params['clerk_code'];
  111. $clerk_code_pre = $clerk_code[0] . $clerk_code[1];
  112. $t = Yii::$app->db->beginTransaction();
  113. try {
  114. $order = Order::findOne(['clerk_code'=> $params['clerk_code']]);
  115. $order_no=$order['order_no'];
  116. $store_order = HappinessOrder::getOne([['order_no' => $order['order_no']], ['mall_id' => $params['mall_id']], ['store_id' => $params['store_id']]]);
  117. if (empty($store_order)) throw new \Exception('订单不存在');
  118. if ($order->order_status != OrderStatusEnum::TAKE) throw new \Exception('该订单不是待自提');
  119. if ($order->order_status == OrderStatusEnum::ACCOMPLISH) throw new \Exception('已自提');
  120. if ($order->shipping_type != ShippingTypeEnum::PICKUP) throw new \Exception('该订单不是自提订单');
  121. //获取订单详情
  122. $detail = OrderDetail::lists([
  123. 'where' => [
  124. ['mall_id' => $params['mall_id']],
  125. ['order_id' => $order['id']],
  126. ],
  127. ]);
  128. if (empty($detail)) throw new Exception('订单不存在');
  129. foreach ($detail as $key => $value) {
  130. if ($value['is_feedback'] == 1) throw new Exception('存在售后中商品,无法完成订单');
  131. }
  132. if($order){
  133. $order->order_status = OrderStatusEnum::ACCOMPLISH;
  134. $order->consign_time = time();
  135. $order->sign_time = time();
  136. $order->finish_time = time();
  137. $res = $order->save();
  138. if($res==false) throw new \Exception($order->getErrorMessage());
  139. }
  140. // 维护累计核销金额及累计核销订单数
  141. $params['order_no'] = $order['order_no'];
  142. $params['user_id'] = $order['user_id'];
  143. $params['mobile'] = $order['mobile'];
  144. $happiness_clerk = HappinessClerk::getOne([
  145. ['mall_id' => $params['mall_id']],
  146. ['id' => $params['clerk_id']],
  147. ['store_id' => $params['store_id']],
  148. ['status' => StatusEnum::ENABLED]
  149. ]);
  150. if (!empty($happiness_clerk)) {
  151. $nums = OrderDetail::find()->where(['order_id'=>$order['id']])->sum('num');
  152. $happiness_clerk->nums += $nums;
  153. $happiness_clerk->total_money += $order['pay_money'];
  154. $happiness_clerk->save();
  155. }
  156. //记录核销日志
  157. $model = new self();
  158. $model->loadDefaultValues();
  159. if (!$model->load($params, '')) throw new \Exception($model->getErrorMessage());
  160. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  161. $t->commit();
  162. // 触发订单过售后事件,事务提交完成后触发
  163. $event = new OrderFinishEvent($params['mall_id']);
  164. $order_data['id'] = $order['id'];
  165. $order_data['order_no'] = $order['order_no'];
  166. $order_data['operator_id'] = $params['operator_id'] ?? 0;
  167. $order_data['operator_name'] = $params['operator_name'] ?? '系统';
  168. Yii::$app->services->events->dispatch($event, $order_data, $event->listeners);
  169. return $model;
  170. } catch (\Exception $e) {
  171. $t->rollBack();
  172. // var_dump($e->getMessage());
  173. self::$static_error = $e->getMessage();
  174. return false;
  175. }
  176. }
  177. public static function clerkPlatformStoreOrderDetail($params)
  178. {
  179. try {
  180. $mall_id = $params['mall_id'];
  181. if (!MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_PLATFORM_STORE_CLERK)) {
  182. throw new \Exception('请安装门店核销员插件');
  183. }
  184. $clerk_detail = PlatformStoreClerkOrderDetail::getOrderByCode($mall_id, $params['clerk_code'],false);
  185. if (!$clerk_detail) throw new \Exception('该订单不存在');
  186. if ($clerk_detail->clerk_status !== 0) throw new \Exception('该订单已核销');
  187. // $rse = StoreClerk::getOne([['mall_id' => $mall_id], ['user_id' => $params['user_id']], ['status' => StatusEnum::ENABLED]],true);
  188. $clerk_list = HappinessClerk::find()->where(['mall_id' => $mall_id,'user_id' => $params['user_id'],'status' => StatusEnum::ENABLED])->asArray()->all();
  189. if(!$clerk_list) throw new \Exception('你不是核销员');
  190. $clerk_store = array_column($clerk_list,null,'store_id');
  191. $clerk_store_ids = array_keys($clerk_store);
  192. //$store_id = $rse['store_id'];
  193. $goods_setting = PlatformStoreClerkGoodsSetting::getGoodsInfo($mall_id,$clerk_detail->goods_id);
  194. if(!$goods_setting) throw new \Exception('商品尚未关联该门店');
  195. $cate_id = $goods_setting['cate_id'];
  196. $is_bind_store = $goods_setting['is_bind_store'] ?? 0;
  197. $where = ['id' => $clerk_store_ids,'status' => StatusEnum::ENABLED];
  198. if($is_bind_store > 0 && $cate_id){
  199. $where['c_id'] = $cate_id;
  200. }
  201. $store_list = HappinessStore::find()->where($where)->select('id')->asArray()->all();
  202. if(!$store_list) throw new \Exception('商品尚未关联该门店');
  203. $store_id = $store_list[0]['id'];
  204. $clerk_user_id = $clerk_store[$store_id]['user_id'];
  205. //$store_ids = explode(',',$goods_setting['store_ids']);
  206. // $rse = StoreClerk::getOne([['mall_id' => $mall_id], ['user_id' => $params['user_id']], ['status' => StatusEnum::ENABLED],['store_id' => $store_ids]],true);
  207. //
  208. // if (empty($rse)) throw new \Exception('你不是核销员');
  209. // $store_id = $rse['store_id'];
  210. //
  211. // if(!in_array($store_id,$store_ids)) throw new \Exception('商品尚未关联该门店');
  212. //$order = Order::findOne(['id' => $clerk_detail->order_id]);
  213. //$order_detail = OrderDetail::findOne(['id' => $clerk_detail->order_detail_id]);
  214. //核销操作
  215. $clerk_detail->clerk_status = 1;
  216. $clerk_detail->clerk_time = time();
  217. $clerk_detail->clerk_store_id = $store_id;
  218. $clerk_detail->clerk_user_id = $clerk_user_id;
  219. $clerk_detail->save();
  220. if($clerk_detail->reward_num > 0){
  221. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, ['clerk_detail_id' => $clerk_detail->id,'store_id' => $store_id], PlatformStoreClerkOrderDetail::class, 'sendStoreReward');
  222. //发放核销奖励
  223. // $insert_wallet[] = [
  224. // 'mall_id' => $mall_id,
  225. // 'user_id' => $rse['user_id'],
  226. // 'is_frozen' => false,
  227. // 'wallet_type' => 'commission',
  228. // 'money' => $clerk_detail->reward_num,
  229. // 'desc' => '核销奖励',
  230. // 'source_table' => PlatformStoreClerkOrderDetail::tableName(),
  231. // 'source_table_id' => $clerk_detail->id,
  232. // 'from_type' => AddonsEnum::ADDONS_NAME_PLATFORM_STORE_CLERK,
  233. // 'capital_type' => 'store_clerk_order',
  234. // 'order_no' => $order['order_no'],
  235. // 'contributor_name' => $order_detail['goods_name']
  236. // ];
  237. //$res = UserWalletService::batchHandleByQueue($insert_wallet);
  238. //if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
  239. }
  240. $goods = Goods::findOne(['id'=>$clerk_detail->goods_id]);
  241. $store = HappinessStore::getOne([['id' => $store_id]], true, [], false, 'id,user_id,balance,logo_img,store_name');
  242. $order_detail = OrderDetail::findOne(['id'=>$clerk_detail['order_detail_id']]);
  243. $add_clerk_log_data = [
  244. 'mall_id' => $params['mall_id'],
  245. 'user_id' => $params['user_id'],
  246. 'mall_logo' => $store['logo_img']??'',
  247. 'mall_name' => $store['store_name']??'',
  248. 'name' => $goods['goods_name'],
  249. 'pic' => $order_detail['pic_url'],
  250. 'clerk_code' => (string)$params['clerk_code'],
  251. 'type' => ClerkEnum::PLATFORM_ORDER_BY_O2O_STORE_CLERK_CODE_PRE,
  252. 'extra' => json_encode([
  253. 'pay_money' => $order_detail['goods_price'],
  254. 'order_money' => $order_detail['goods_price'],
  255. 'clerk_nums' => $order_detail['num']??0,
  256. 'subtitle' => $goods['subtitle']??'',
  257. 'platform_store_clerk_order_detail_id' => $clerk_detail['id'],
  258. ]),
  259. ];
  260. $clerk_log_model = \common\models\common\ClerkLog::setData($add_clerk_log_data);
  261. if ($clerk_log_model == false) {
  262. throw new \Exception(\common\models\common\ClerkLog::getStaticError());
  263. }
  264. // 维护累计核销金额及累计核销订单数
  265. $storeClerkFind = HappinessClerk::find();
  266. HappinessClerk::paramPack([
  267. 'where' => [['mall_id' => $params['mall_id']], ['user_id' => $clerk_user_id], ['store_id' => $store_id], ['status' => StatusEnum::ENABLED]],
  268. 'select' => 'id'
  269. ], $storeClerkFind);
  270. if ($storeClerkId = $storeClerkFind->scalar()) {
  271. $nums = OrderDetail::find()->where(['order_id'=>$clerk_detail->order_id])->sum('num');
  272. $order = Order::findOne(['id' => $clerk_detail->order_id]);
  273. HappinessClerk::incrNumsAndTotalMoney($storeClerkId, $nums, $order['pay_money'] ?? 0);
  274. }
  275. $event = new StoreSelfPickupOrderClerkEvent($params['mall_id']);
  276. $data['id'] = $clerk_detail['order_id'];
  277. Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  278. return true;
  279. } catch (\Exception $e) {
  280. self::$static_error = $e->getMessage();
  281. Yii::error('clerkPlatformStoreOrderDetail error:'.$e->getMessage().' File:'.$e->getFile().' Line:'.$e->getLine(), 'addons\Store\common\models\StoreClerkLog');
  282. return false;
  283. }
  284. }
  285. public static function getPlatformStoreOrderDetail($params)
  286. {
  287. // $order_detail_id = $params['order_detail_id'];
  288. $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,
  289. 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,clerk_code';
  290. $where = [];
  291. $where[] = ['mall_id' => $params['mall_id']];
  292. $where[] = ['order_no' => $params['order_no']];
  293. $order = Order::getOne($where, true, ['detail'], false, $select);
  294. if (empty($order) ) {
  295. throw new \Exception('该订单不存在');
  296. }
  297. $rse = HappinessClerk::getOne([['mall_id' => $params['mall_id']], ['user_id' => $params['user_id']], ['status' => StatusEnum::ENABLED]],true);
  298. if (empty($rse)){
  299. throw new \Exception('你不是核销员');
  300. }
  301. $clerk_list = HappinessClerk::find()->where(['mall_id' => $params['mall_id'],'user_id' => $params['user_id'],'status' => StatusEnum::ENABLED])->asArray()->all();
  302. if(!$clerk_list){
  303. throw new \Exception('你不是核销员');
  304. }
  305. $clerk_store = array_column($clerk_list,null,'store_id');
  306. $clerk_store_ids = array_keys($clerk_store);
  307. $where = ['id' => $clerk_store_ids,'status' => StatusEnum::ENABLED];
  308. $store_list = HappinessStore::find()->where($where)->select('id')->asArray()->all();
  309. if(!$store_list) {
  310. throw new \Exception('商品尚未关联该门店');
  311. }
  312. $store_id = $store_list[0]['id'];
  313. $clerk_user_id = $clerk_store[$store_id]['user_id'];
  314. $marketing = OrderMarketing::getMarketingInfo($order);
  315. $order['order_status_text'] = OrderStatusEnum::getMap();
  316. $order['is_feedback_text'] = OrderStatusEnum::getFeedbackMap();
  317. $order['shipping_type_text'] = ShippingTypeEnum::getMap();
  318. $order['payment_type_text'] = PayTypeEnum::getMap();
  319. $order['pay_type_list'] = \Yii::$app->services->pay->getEnablePayment($params['mall_id'],$params['platform']);
  320. $adjust_money = array_sum(array_column($order['detail'], 'adjust_money'));//预留字段
  321. if ($adjust_money) {
  322. $order['change_price'] = $adjust_money;
  323. }
  324. $order['marketing'] = $marketing;
  325. $order['marketing_type_map'] = MarketingTypeEnum::getMap();
  326. $order_setting = Yii::$app->services->setting->mall->get($params['mall_id'], 'order');
  327. $order['payment_expire_time'] = $order_setting['payment_expire_time'] ?? 30;
  328. $order['auto_receiving_time'] = $order_setting['auto_receiving_time'] ?? 14;
  329. // 获取订单详情的状态文字描述
  330. $order['status_text'] = OrderStatusEnum::getApiStatus($order['status'], $order['shipping_type']);
  331. $order['status'] == OrderStatusEnum::NOT_PAY && $order['status_text']['desc'] = $order['payment_expire_time'] . $order['status_text']['desc'];
  332. $order['status'] == OrderStatusEnum::SHIPMENTS && $order['status_text']['desc'] = $order['auto_receiving_time'] . $order['status_text']['desc'];
  333. // 公共调用
  334. $order = GlobalInvoke::exec(GlobalInvoke::ORDER_DETAIL, $params['mall_id'], [
  335. 'order' => $order,
  336. 'mall_id' => $params['mall_id'],
  337. ]) ?: $order;
  338. $order['store_name'] = $order['happiness_store']['store_name'];
  339. $order['show_clerk_button'] = $order['order_status'] == OrderStatusEnum::TAKE ? 1:0;
  340. // $order['clerk_code'] = $order['clerk_code'];
  341. // $order['pay_money'] = $order['detail'][0]['goods_price'];
  342. return $order;
  343. }
  344. public static function clerkStoreVerification($params){
  345. try {
  346. $key = sprintf('StoreVerification:%s', $params['clerk_code']);
  347. if (LockHelper::fLock($key)) throw new \Exception('请勿频繁请求');
  348. StoreVerificationCouponsClerkLog::clerkStoreVerificationByClerkCode($params);
  349. LockHelper::unFLock($key);
  350. return true;
  351. } catch (\Exception $e) {
  352. LockHelper::unFLock($key);
  353. self::$static_error = $e->getMessage();
  354. return false;
  355. }
  356. }
  357. public static function clerkStoreVerificationByClerkCode($params){
  358. $key = sprintf('StoreVerification:%s', $params['mall_id'].$params['clerk_code']);
  359. try {
  360. if (LockHelper::fLock($key)) throw new \Exception('请勿频繁请求');
  361. StoreVerificationCouponsClerkLog::clerkStoreVerificationByClerkCode($params);
  362. LockHelper::unFLock($key);
  363. return true;
  364. } catch (\Exception $e) {
  365. LockHelper::unFLock($key);
  366. self::$static_error = $e->getMessage();
  367. return false;
  368. }
  369. }
  370. }