HiBeiLogic.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <?php
  2. namespace addons\HiGo\common\logic;
  3. use addons\HiGo\common\enums\HiGoEnum;
  4. use addons\HiGo\common\models\HigoGoodsSetting;
  5. use addons\HiGo\common\models\HigoHibeiLog;
  6. use addons\HiGo\common\models\HigoMall;
  7. use addons\HiGo\common\models\HigoStoreGoodsMode;
  8. use addons\HiGo\common\models\HigoWallet;
  9. use addons\HiGo\common\models\HigoWalletFrozenLog;
  10. use addons\HiGo\common\models\HigoWalletLog;
  11. use addons\Store\common\models\Store;
  12. use common\enums\AddonsEnum;
  13. use common\enums\StatusEnum;
  14. use common\models\census\CensusMall;
  15. use common\models\common\CapitalLog;
  16. use common\models\mall\MallAddons;
  17. use common\models\order\Order;
  18. use common\models\order\OrderDetail;
  19. use common\models\order\OrderMarketing;
  20. use common\traits\ErrorTrait;
  21. use Exception;
  22. use yii\helpers\Json;
  23. /**
  24. * Class HiValueLogic
  25. * 嗨呗逻辑类
  26. * @Author: mz
  27. * @DateTime: 2022/11/16 16:39
  28. * @Copyright: copyright (c) 2022 广东七件事集团
  29. */
  30. class HiBeiLogic
  31. {
  32. use ErrorTrait;
  33. /**
  34. * 获取嗨呗当前价值【1个嗨呗 = 多少元】
  35. * @param int $mall_id
  36. * @return
  37. */
  38. public static function getNowPrice($mall_id)
  39. {
  40. $setting = \Yii::$app->services->setting->addons->get($mall_id, HiGoEnum::ADDONS_NAME, 'basic');
  41. if(!$setting['hi_bei_pricing_method']){
  42. //自定义
  43. $price = $setting['hi_bei_pricing'] ?? 0;
  44. } else{
  45. //自动按总营业的百分比/发行的总量
  46. $census_mall = CensusMall::findOne(['mall_id' => $mall_id]);
  47. $total_pay_money = $census_mall['total_pay_money'] ?? 0;
  48. $higo_mall = HigoMall::findOne(['mall_id' => $mall_id]);
  49. $hi_bei_pricing_radio = $setting['hi_bei_pricing_radio'] ?? 0;
  50. //价格是否 到小数点2位
  51. $price = bcmul($total_pay_money,$hi_bei_pricing_radio/100,2);
  52. if($higo_mall['hi_bei'] <= 0){
  53. $price = 0;
  54. }else{
  55. $price = bcdiv($price,$higo_mall['hi_bei'],2);
  56. }
  57. }
  58. $price = $price > 0 ? $price : 0;
  59. return $price;
  60. }
  61. /**
  62. * 嗨呗空投
  63. * @param $mall_id
  64. * @return bool
  65. * @throws Exception
  66. */
  67. public static function airdrop($mall_id)
  68. {
  69. $setting = \Yii::$app->services->setting->addons->get($mall_id, HiGoEnum::ADDONS_NAME, 'basic');
  70. $total_num = $setting['hi_bei_total_issuance'];
  71. $day_num = 0;
  72. //每天空投数量
  73. if($setting['airdrop_method'] == 0){
  74. //每天
  75. $day_num = $setting['airdrop_everyday_number'] ?? 0;
  76. }else{
  77. //每年
  78. $is_percent = $setting['airdrop_years_type'] ?? 0;
  79. //计算今年的数量
  80. $airdrop_years_config = json_decode($setting['airdrop_years_config'],true);
  81. $airdrop_years_config = array_column($airdrop_years_config,null,'year');
  82. $year = date('Y');
  83. $now_year_config = $airdrop_years_config[$year] ?? [];
  84. $year_num = $is_percent == 1 ? bcmul($total_num,$now_year_config['value']/100,10) : $now_year_config['value'];
  85. $day_num = bcdiv($year_num,self::cal_days_in_year($year),10);
  86. }
  87. //判断 总发行 是否超出
  88. $higo_mall = HigoMall::findOne(['mall_id' => $mall_id]);
  89. if(bcadd($higo_mall->hi_bei,$day_num) > $total_num){
  90. //超出
  91. $day_num = bcsub($total_num,$higo_mall->hi_bei,10);
  92. $day_num = $day_num > 0 ? $day_num : 0;
  93. }
  94. if($day_num > 0){
  95. $where = [
  96. 'and',
  97. ['mall_id' => $mall_id],
  98. ['>', 'hi_value', 0],
  99. ['status' => StatusEnum::ENABLED],
  100. ];
  101. $total_num = 0;
  102. //发放嗨呗
  103. foreach (HigoWallet::find()->where($where)->each(500) as $user_wallet) {
  104. $send_num = bcdiv($user_wallet->hi_value,$higo_mall->hi_value,10);
  105. $send_num = bcmul($send_num,$day_num,10);
  106. $desc = '每天空投释放奖励';
  107. $wallet_log = [
  108. 'mall_id' => $user_wallet->mall_id,
  109. 'user_id' => $user_wallet->user_id,
  110. 'change_type' => CapitalLog::CHANGE_TYPE_ADD,
  111. 'change_num' => $send_num,
  112. 'desc' => $desc,
  113. 'source_table' => '',
  114. 'source_table_id' => 0,
  115. 'from_type' => HiGoEnum::FROM_TYPE_AIRDROP,
  116. 'wallet_type' => HiGoEnum::WALLET_TYPE_HI_BEI,
  117. 'is_send' => true
  118. ];
  119. WalletLogic::handleInQueue($wallet_log);
  120. $total_num = bcadd($total_num,$send_num,10);
  121. }
  122. //添加嗨呗记录
  123. $desc = date('Y-m-d').'系统嗨呗空投';
  124. HigoHibeiLog::setData(['mall_id' => $mall_id,'change_type' => CapitalLog::CHANGE_TYPE_ADD,'change_num'=>$total_num,'from_type' => HigoHibeiLog::FROM_TYPE_AIRDROP,'desc' => $desc,'setting' => json_encode($setting)]);
  125. }
  126. return true;
  127. }
  128. /**
  129. * 计算今年天数
  130. * @param $year
  131. * @return int
  132. */
  133. public static function cal_days_in_year($year){
  134. $days=0;
  135. for($month=1;$month<=12;$month++){
  136. //$days = $days + cal_days_in_month(CAL_GREGORIAN,$month,$year);
  137. $days = $days + date("t",strtotime("$year-$month"));
  138. }
  139. return $days;
  140. }
  141. /**
  142. * 商品设置营销赠送嗨呗-商城订单、门店订单、多商户 发放嗨呗
  143. * @param $order
  144. * @throws
  145. * @return bool
  146. *
  147. */
  148. public static function sendGoodsSettingHiBei($order)
  149. {
  150. $mall_id = $order['mall_id'];
  151. $user_id = $order['user_id'];
  152. $source_table = Order::tableName();
  153. $from_type= HiGoEnum::FROM_TYPE_ORDER_GOODS;
  154. //嗨值自定义名称
  155. $setting = \Yii::$app->services->setting->addons->get($mall_id, HiGoEnum::ADDONS_NAME, 'basic');
  156. $name = $setting['hi_bei_name'] ?? '嗨贝';
  157. //查询订单商品
  158. $order_goods = OrderDetail::find()->where(['order_id' => $order['id']])->asArray()->all();
  159. foreach ($order_goods as $info){
  160. $is_frozen = false;
  161. $source = $order['store_id'] > 0 ? 'Store' : 'Main';
  162. $goods_setting = HigoGoodsSetting::getGoodsSetting($info['goods_id'],HiGoEnum::WALLET_TYPE_HI_BEI,$source);
  163. if(!$goods_setting) continue;
  164. //检测该订单是否发放过该奖励
  165. if(HigoWalletLog::checkSend($mall_id,$user_id,$source_table,$order['id'],$from_type,HiGoEnum::WALLET_TYPE_HI_BEI)){
  166. continue;
  167. }
  168. //查询冻结表是否有记录
  169. if(HigoWalletFrozenLog::checkSend($mall_id,$user_id,$source_table,$order['id'],$from_type,HiGoEnum::WALLET_TYPE_HI_VALUE)){
  170. continue;
  171. }
  172. if($goods_setting['settlement_method'] == HiGoEnum::SETTLEMENT_METHOD_AFTER_FINISH){
  173. //订单完成时结算,先存入冻结记录表,待订单完成时去 结算该奖励
  174. $is_frozen = true;
  175. }
  176. $change_num = $goods_setting['give'];
  177. //计算赠送嗨呗
  178. if($goods_setting['is_percent'] == 1){
  179. //百分比
  180. $change_num = bcmul($info['goods_price'],$goods_setting['give']/100,10);
  181. }
  182. if($order['store_id'] > 0){
  183. if (MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_STORE)){
  184. //检测门店账号是否有嗨呗
  185. $store = Store::findOne(['id' => $order['store_id']]);
  186. $store_user_id = $store['user_id'] ?? 0;
  187. if(!$store_user_id) continue;
  188. $store_wallet = HigoWallet::findOne(['user_id' => $store_user_id,'mall_id' =>$mall_id ]);
  189. if(!$store_wallet || bccomp($change_num,$store_wallet->hi_bei,10) > 0 ){
  190. //门店嗨呗不足
  191. \Yii::error('发放失败,门店嗨呗不足,订单发放嗨呗,order_id='.$order['id'].' ,需发放嗨呗数量:'.$change_num);
  192. continue;
  193. }
  194. //先扣除门店的嗨呗
  195. $desc = '门店商品营销设置赠送'.$name.',订单ID('.$order['id'].')';
  196. $wallet_log = [
  197. 'mall_id' => $mall_id,
  198. 'user_id' => $store_user_id,
  199. 'change_type' => CapitalLog::CHANGE_TYPE_SUB,
  200. 'change_num' => $change_num * -1,
  201. 'desc' => $desc,
  202. 'source_table' => $source_table,
  203. 'source_table_id' => $order['id'],
  204. 'from_type' => $from_type,
  205. 'wallet_type' => HiGoEnum::WALLET_TYPE_HI_BEI,
  206. 'is_send' => 0,
  207. 'addon_name' => HiGoEnum::ADDONS_NAME,
  208. 'setting' => json_encode($goods_setting)
  209. ];
  210. $res = WalletLogic::handleInQueue($wallet_log,true);
  211. }
  212. }else{
  213. if(!self::checkAddHibei($mall_id,$change_num)){
  214. //系统嗨呗不足
  215. \Yii::error('发放失败,系统嗨呗不足,商城订单发放嗨呗,order_id='.$order['id'].' ,需发放嗨呗数量:'.$change_num);
  216. continue;
  217. }
  218. }
  219. $desc = '用户('.$user_id.')获得订单ID('.$order['id'].'),门店商品营销设置赠送'.$name;
  220. $wallet_log = [
  221. 'mall_id' => $mall_id,
  222. 'user_id' => $user_id,
  223. 'change_type' => CapitalLog::CHANGE_TYPE_ADD,
  224. 'change_num' => $change_num,
  225. 'desc' => $desc,
  226. 'source_table' => $source_table,
  227. 'source_table_id' => $order['id'],
  228. 'from_type' => $from_type,
  229. 'wallet_type' => HiGoEnum::WALLET_TYPE_HI_BEI,
  230. 'is_send' => $order['store_id'] > 0 ? 0: 1,
  231. 'addon_name' => HiGoEnum::ADDONS_NAME,
  232. 'setting' => json_encode($goods_setting)
  233. ];
  234. if($is_frozen){
  235. $res = HigoWalletFrozenLog::setData($wallet_log);
  236. if(!$res) throw new Exception( HigoWalletFrozenLog::getStaticError());
  237. }else{
  238. $res = WalletLogic::handleInQueue($wallet_log,true);
  239. if(!$res) throw new Exception('sendMallOrderHiBei handleInQueue error');
  240. }
  241. }
  242. return true;
  243. }
  244. /**
  245. * 商户订单发放嗨呗
  246. * @param $order
  247. * @param int $settlement_method
  248. * @return bool|void
  249. */
  250. public static function sendMerchantOrderHiBei($order,$settlement_method = 0)
  251. {
  252. $mall_id = $order['mall_id'];
  253. $user_id = $order['user_id'];
  254. $source_table = Order::tableName();
  255. $from_type= HiGoEnum::FROM_TYPE_ORDER_GOODS;
  256. //嗨呗自定义名称
  257. $setting = \Yii::$app->services->setting->addons->get($mall_id, HiGoEnum::ADDONS_NAME, 'basic');
  258. $name = $setting['hi_bei_name'] ?? '嗨贝';
  259. if (empty($setting['merchant_buy_goods'])) return ;
  260. if($settlement_method != $setting['payment_method'] ) return ;
  261. return true;
  262. }
  263. /**
  264. * 检测系统是否可以增加嗨呗
  265. * @param $mall_id
  266. * @param $add_num
  267. * @return bool
  268. */
  269. public static function checkAddHibei($mall_id,$add_num)
  270. {
  271. $result = true;
  272. $setting = \Yii::$app->services->setting->addons->get($mall_id, HiGoEnum::ADDONS_NAME, 'basic');
  273. //判断 总发行 是否超出
  274. $higo_mall = HigoMall::findOne(['mall_id' => $mall_id]);
  275. if(bccomp(bcadd($higo_mall->hi_bei,$add_num),$setting['hi_bei_total_issuance'],10) > 0 ){
  276. $result = false;
  277. }
  278. return $result;
  279. }
  280. /**
  281. * 嗨贝,嗨值返回
  282. * @Author: lun
  283. * @DateTime: 2022/9/21 0021 9:54
  284. * @Copyright: copyright (c) 2021 广东七件事集团
  285. * @param $order_detail_id
  286. * @param array $params
  287. * @return bool
  288. */
  289. public static function backGoodsMarketing($order_detail_id, $params = [])
  290. {
  291. //$trans = \Yii::$app->db->beginTransaction();
  292. try {
  293. $deduct = OrderMarketing::find()->select('deduct_currency')->where(['order_detail_id' => $order_detail_id, 'status' => StatusEnum::ENABLED])->scalar();
  294. if (empty($deduct)) {
  295. //$trans->commit();
  296. return true;
  297. }
  298. $deduct_arr = Json::decode($deduct, true);
  299. foreach ($deduct_arr as $key => $item) {
  300. // 判断里面是否存在嗨贝跟嗨值
  301. if (in_array($key, [HigoEnum::WALLET_TYPE_HI_BEI, HigoEnum::WALLET_TYPE_HI_VALUE]) && $item['money'] > 0) {
  302. $wallet_log = [
  303. 'mall_id' => $params['mall_id'],
  304. 'user_id' => $params['user_id'],
  305. 'source_table' => $params['source_table'],
  306. 'source_table_id' => $params['source_table_id'],
  307. 'from_type' => $params['from_type'],
  308. 'desc' => $params['desc'] ?? '',
  309. 'change_type' => CapitalLog::CHANGE_TYPE_ADD,
  310. 'change_num' => $item['money'],
  311. 'wallet_type' => $key,
  312. ];
  313. $res = WalletLogic::handleInQueue($wallet_log);
  314. if ($res == false) throw new Exception(WalletLogic::getStaticError());
  315. }
  316. }
  317. //$trans->commit();
  318. return true;
  319. } catch (\Exception $e) {
  320. //$trans->rollBack();
  321. self::setStaticError($e->getMessage());
  322. return false;
  323. }
  324. }
  325. /**
  326. * 门店,多商户订单 售后退回赠送的嗨呗
  327. * @param $order_id
  328. * @param $source_table
  329. * @param $source_table_id
  330. * @param $from_type
  331. * @return bool
  332. * @throws Exception
  333. */
  334. public static function backMchOrder($order_id,$source_table,$source_table_id)
  335. {
  336. $mch_hi_bei_logs = HigoWalletLog::findAll([
  337. 'wallet_type' => HiGoEnum::WALLET_TYPE_HI_BEI,
  338. 'change_type' => 'sub',
  339. 'source_table' => $source_table,
  340. 'source_table_id' => $source_table_id,
  341. 'status' => StatusEnum::ENABLED,
  342. //'from_type' => $from_type
  343. ]);
  344. foreach($mch_hi_bei_logs as $log){
  345. $back_wallet_log = [
  346. 'mall_id' => $log['mall_id'],
  347. 'user_id' => $log['user_id'],
  348. 'source_table' => $log['source_table'],
  349. 'source_table_id' => $log['source_table_id'],
  350. 'from_type' => HiGoEnum::FROM_TYPE_ORDER_REFUND_BACK,
  351. 'desc' => '订单ID:'.$order_id.'售后完成,营销赠送退回',
  352. 'change_type' => CapitalLog::CHANGE_TYPE_ADD,
  353. 'change_num' => $log['change_num'],
  354. 'wallet_type' => HiGoEnum::WALLET_TYPE_HI_BEI,
  355. 'is_send' => false
  356. ];
  357. $res = WalletLogic::handleInQueue($back_wallet_log,false);
  358. if(!$res){
  359. echo WalletLogic::getStaticError();
  360. }
  361. }
  362. return true;
  363. }
  364. }