PvMarketing.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace addons\Happiness\common\logic\order\marketing;
  3. use addons\Happiness\common\enums\HappinessPvEnum;
  4. use addons\Happiness\common\models\HappinessPvWallet;
  5. use addons\Happiness\common\service\PvService;
  6. use common\enums\AppEnum;
  7. use common\enums\StatusEnum;
  8. use common\traits\ErrorTrait;
  9. use Yii;
  10. class PvMarketing
  11. {
  12. use ErrorTrait;
  13. public static function compute($item, &$form, array &$extra = [])
  14. {
  15. try {
  16. $mall_id = $item['mch_order_info']['mall_id'];
  17. $user_id = $item['mch_order_info']['user_id'];
  18. $deduct_money = 0;// 抵扣总额
  19. $deduct_arr = [];// 抵扣冻结跟金额数组
  20. //同步积分
  21. $power_name='幸福宝积分';
  22. $pvService=new PvService();
  23. $uid=$pvService->syncUserPv($user_id);
  24. if($uid===false){
  25. throw new \Exception($pvService->getError());
  26. }
  27. // 商品处理
  28. $user_power_wallet = HappinessPvWallet::findOne(['user_id'=>$user_id, 'status' => StatusEnum::ENABLED]);
  29. if(!$user_power_wallet || $user_power_wallet->score_value<=0)
  30. {
  31. return $item;
  32. }
  33. $value['deduct_type']=1;//单件抵扣
  34. $value['is_deduct_percent']=1;//百分比抵扣
  35. $value['deduct_money']=100;//百分百
  36. foreach ($item['goods'] as $goods_id => &$goods) {
  37. // 单件抵扣:比如单件抵扣10元,购买A商品共3件,每件50元,总价=150元,可抵扣的金额30元
  38. // 多件抵扣:比如多件抵扣10元,购买A商品共3件,每件50元,总价=150元,可抵扣的金额10元
  39. $total_goods_price = array_sum(array_column($goods['goods_details'],'goods_price'));//同一种商品不同规格总价格
  40. $total_num = array_sum(array_column($goods['goods_details'],'num'));// 同一种商品不同规格总数量
  41. if (!empty($value['is_deduct_percent'])) {
  42. // 按照百分比抵扣 = 商品金额 * 设置比例 / 100;百分比抵扣跟商品数量无关
  43. $money = $item['goods'][$goods_id]['goods_price'] * bcdiv($value['deduct_money'],100,2);
  44. } else {
  45. // 固定金额抵扣
  46. $money = $value['deduct_type'] == 2 ? $value['deduct_money'] : $value['deduct_money'] * $total_num;// 计算抵扣金额
  47. }
  48. if($user_power_wallet['score_value']<$money){
  49. $money = $user_power_wallet['score_value'];
  50. }
  51. $user_power_wallet['score_value'] -= $money;// 余额逐步减少
  52. if($money<=0) continue;
  53. $pv_score_en = 'pv_score';
  54. // 检查是否有被选中
  55. $temp_total_deduct_money = 0;
  56. $is_use = false;
  57. if($total_goods_price<=0) continue;
  58. if (!empty($form->data['is_use_' . $pv_score_en])) $is_use = true;
  59. foreach ($goods['goods_details'] as $k=>&$detail) {
  60. $rate = $detail['goods_price']/$total_goods_price;
  61. if(!isset($goods['goods_details'][$k+1])){
  62. //最后一个
  63. $temp_deduct_money = bcsub($money, $temp_total_deduct_money, 2);
  64. } else {
  65. $temp_deduct_money = bcmul($rate, $money, 2);
  66. }
  67. if( $detail['goods_price']>$temp_deduct_money){
  68. $is_use && $detail['goods_price'] -= $temp_deduct_money;
  69. }else{
  70. $temp_deduct_money = $detail['goods_price'];
  71. $is_use && $detail['goods_price'] =0;
  72. }
  73. $temp_total_deduct_money += $temp_deduct_money;
  74. if ($is_use) {
  75. $deduct_currency = $detail['marketing']['deduct_currency'];
  76. if($deduct_currency){
  77. $deduct_currency = json_decode($deduct_currency,true);
  78. $deduct_currency = (array_merge($deduct_currency, [$pv_score_en => ['name' => $power_name,'money' => $temp_deduct_money]]));// 将合并的数组转为json字符串
  79. }else{
  80. $deduct_currency = [$pv_score_en => ['name' => $power_name,'money' => $temp_deduct_money]];
  81. }
  82. $detail['marketing']['deduct_currency'] = json_encode($deduct_currency);// 插入order_marketing表数据
  83. }
  84. }
  85. if ($is_use) {
  86. $item['goods'][$goods_id]['goods_price'] -= $temp_total_deduct_money;// 此商品减扣后的金额计算
  87. if($item['goods'][$goods_id]['goods_price']<0) $item['goods'][$goods_id]['goods_price'] = 0;
  88. $deduct_arr[$pv_score_en] = empty($deduct_arr[$pv_score_en]) ? $temp_total_deduct_money : $deduct_arr[$pv_score_en] + $temp_total_deduct_money;
  89. }
  90. // 前端抵扣数据展示组合
  91. if ($form->action == AppEnum::ACTION_PREVIEW) {
  92. $form->marketing['deduct']['pv_score'] = [
  93. 'name' => $power_name,
  94. 'deduct_val' => empty($form->marketing['deduct']['pv_score']['deduct_val']) ? round($temp_total_deduct_money, 2) : bcadd($form->marketing['deduct']['pv_score']['deduct_val'], $temp_total_deduct_money, 2),
  95. 'money' => empty($form->marketing['deduct']['pv_score']['money']) ? round($temp_total_deduct_money, 2) : bcadd($form->marketing['deduct']['pv_score']['money'], $temp_total_deduct_money, 2),
  96. 'is_show_radio' => true,// 是否显示单选按钮
  97. 'is_use' => $is_use,// 是否被选中单选按钮
  98. ];
  99. }
  100. $is_use && $deduct_money += $temp_total_deduct_money;
  101. }
  102. // 计算订单减扣后的金额
  103. if ($deduct_money > 0) {
  104. $item['mch_order_info']['pay_money'] -= $deduct_money;
  105. $item['mch_order_info']['goods_price'] = bcsub(floatval($item['mch_order_info']['goods_price']), $deduct_money, 2);
  106. // 扣减积分金额
  107. if ($form->action == AppEnum::ACTION_CREATE && $deduct_arr) {
  108. foreach ($deduct_arr as $key => $deduct_big_power_money) {
  109. self::checkScore($mall_id, $user_id, $deduct_big_power_money);
  110. }
  111. }
  112. }
  113. return $item;
  114. } catch (\Exception $e) {
  115. self::setStaticError($e->getMessage());
  116. return false;
  117. }
  118. }
  119. /**
  120. * 检测用户余额是否足够
  121. * @param $mall_id
  122. * @param $user_id
  123. * @param $money
  124. * @param $redpack_type
  125. * @return void
  126. * @throws \Exception
  127. */
  128. public static function checkScore($mall_id, $user_id, $money)
  129. {
  130. $wallet = HappinessPvWallet::findOne(['user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
  131. if (empty($wallet)) throw new \Exception( "幸福宝积分不足");
  132. if ($wallet[HappinessPvEnum::SCORE_VALUE] < $money) throw new \Exception("幸福宝积分不足");
  133. }
  134. }