AgentMarketing.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. <?php
  2. namespace common\logic\order\marketing;
  3. use addons\Agent\common\enums\ComputingEnum;
  4. use addons\Agent\common\logic\reward\AgentReward;
  5. use addons\Agent\common\models\Agent;
  6. use addons\Agent\common\models\AgentCommissionItemSetting;
  7. use addons\Agent\common\models\AgentLevel;
  8. use addons\Mch\common\models\MchGoodsModel;
  9. use common\enums\AddonsEnum;
  10. use common\enums\StatusEnum;
  11. use common\models\mall\MallAddons;
  12. use Exception;
  13. use phpDocumentor\Reflection\Types\Self_;
  14. use yii\helpers\Json;
  15. /**
  16. * Class AgentMarketing
  17. * @Author: hua
  18. * @DateTime: 2022/1/14 17:22
  19. * @Copyright: copyright (c) 2021 广东七件事集团
  20. * @package common\logic\order\marketing渠道分红
  21. */
  22. class AgentMarketing extends BaseMarketing
  23. {
  24. public function execute($form)
  25. {
  26. }
  27. public static function compute($item, &$form, &$extra)
  28. {
  29. try {
  30. $group_order_goods = $form['group_order_goods'];
  31. $mall_id = $form['mall_id'];
  32. if (!MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_AGENT)) return $item;
  33. $setting = \Yii::$app->services->setting->addons->get($mall_id, AddonsEnum::ADDONS_NAME_AGENT, 'basic');
  34. $user_id = $form->user->id;
  35. $agent = Agent::findOne(['mall_id' => $mall_id, 'user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
  36. if (empty($agent)) return $item;
  37. //是否安装渠道业绩插件
  38. $is_install_agent_base = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_AGENT_BASE);
  39. $goods_deduct = \Yii::$app->services->setting->mall->get($mall_id, 'order.goods_deduct');
  40. //如果安装了渠道业绩插件,并且订单设置-抵扣设置-内购抵扣选择agent_base,则进行抵扣
  41. // if ($is_install_agent_base && $goods_deduct == 'agent_base') return $item;
  42. if (empty($setting['is_self_buy']) || empty($setting['enable_goods_deduct'])) return $item;
  43. $name = 'commission';
  44. $commission_level_setting = self::getCommissionLevelSetting($mall_id, $agent->level, $name);
  45. $commission_agent_goods_setting = self::getAgentGoodsSetting($mall_id,$item['goods'], $name, $agent->level);
  46. $name = 'score';
  47. $score_level_setting = self::getCommissionLevelSetting($mall_id, $agent->level, $name);
  48. $score_agent_goods_setting = self::getAgentGoodsSetting($mall_id,$item['goods'], $name, $agent->level);
  49. $deduct_setting = \Yii::$app->services->setting->mall->get($mall_id, 'score');
  50. $total_deduct_goods_price = 0;
  51. if (empty($extra['total_deduct_money'])) {
  52. $total_deduct_money = 0;
  53. $extra['total_deduct_money'] = $total_deduct_money;
  54. } else {
  55. $total_deduct_money = $extra['total_deduct_money'];
  56. }
  57. $extraAgentMarketingAddons = $form['process_extra_data']['extra_agent_marketing_addons'] ?? [];
  58. $agent_deduct = [];
  59. // 获取多商户商品是否走商品抵扣配置
  60. $mchEnableGoodsDeduct = false;
  61. $isInstallMch = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_MCH);
  62. if ($isInstallMch) {
  63. // 获取配置
  64. $mchEnableGoodsDeduct = !empty(\Yii::$app->services->setting->addons->get($mall_id, AddonsEnum::ADDONS_NAME_MCH, 'mode.enable_agent_goods_deduct'));
  65. }
  66. foreach ($item['goods'] as &$row) {
  67. foreach ($row['goods_details'] as &$v) {
  68. $isMch = false;
  69. if (!empty($v['mch_id'])) {
  70. if (is_numeric($v['mch_id']) && $isInstallMch) {
  71. if (!$mchEnableGoodsDeduct || !MchGoodsModel::isParticipateAgent($mall_id, $v['mch_id'], $v['goods_id'])) {
  72. continue;
  73. }
  74. $isMch = true;
  75. } elseif(!in_array($v['mch_id'], array_merge($extraAgentMarketingAddons, ['StarChain']))) {
  76. continue;
  77. }
  78. }
  79. if (!$isMch) {
  80. // 检测商品是否参与了渠道分红
  81. $item_setting = AgentCommissionItemSetting::find()->select('item_id,is_participate,is_self_buy_alone,is_self_buy,enable_goods_deduct')->where(['item_id' => $row['goods_id'], 'status' => StatusEnum::ENABLED])->asArray()->one();
  82. if (!empty($item_setting) && empty($item_setting['is_participate'])) continue;
  83. //独立设置内购
  84. if(!empty($item_setting['is_self_buy_alone'])){
  85. if (empty($item_setting['is_self_buy']) || empty($item_setting['enable_goods_deduct'])) continue;
  86. }
  87. }
  88. $multiple= $v['num'];
  89. if(!isset($v['marketing']['agent_deduct'])) $v['marketing']['agent_deduct']= 0;
  90. // 多商户
  91. if ($isMch) {
  92. $agent_reward_obj = new \addons\Mch\common\logic\addons\Agent\AgentReward($mall_id, $user_id, $setting, [$agent], $setting['is_self_buy']);
  93. $agent_reward_obj->order_detail = $v;
  94. $temp_commission_level_setting = $agent_reward_obj->getLevelConfig()[$agent->level] ?? [];
  95. } else {
  96. $temp_commission_level_setting = $commission_level_setting;
  97. // liuzhantao注释:下面三行代码,原本这个是写在上面(循环外),但获取不了商品详情,以致于执行getRules()时,获取不了商品详情数据
  98. // 所以写在这里,用$v导入$agent_reward_obj->order_detail里,执行getRules(),就能获取商品详情数据了
  99. // 并且,将 $rules['money'] 代替 $v['price']
  100. $agent_reward_obj = new AgentReward($mall_id, $user_id, $setting, [$agent], $setting['is_self_buy']);
  101. $agent_reward_obj->order_detail = $v;
  102. if (isset($commission_agent_goods_setting[$v['goods_id']])) $temp_commission_level_setting = $commission_agent_goods_setting[$v['goods_id']];
  103. }
  104. $rules = $agent_reward_obj->getRules();
  105. $team_prize = $agent_reward_obj->computing($temp_commission_level_setting, $rules['money'], ComputingEnum::TEAM_PRIZE, $multiple);
  106. $team_prize = bcadd(0, $team_prize, 2);
  107. $total_deduct_money_temp = 0;
  108. if ($team_prize > 0){
  109. $agent_deduct['commission'] = $team_prize;
  110. if($team_prize>$v['goods_price']) $team_prize = $v['goods_price'];
  111. $total_deduct_money += $team_prize;
  112. $total_deduct_goods_price += $team_prize;
  113. $total_deduct_money_temp += $team_prize;
  114. $v['goods_price'] -= $team_prize;
  115. $v['marketing']['agent_deduct'] += $team_prize;
  116. $v['marketing']['pay_money'] = $v['goods_price'];
  117. }
  118. $deduct_money = 0;
  119. if ($deduct_setting['score_deduct_status'] == 1) {
  120. if ($isMch) {
  121. $agent_reward_obj->name = 'score';
  122. $temp_score_level_setting = $agent_reward_obj->getLevelConfig()[$agent->level] ?? [];
  123. } else {
  124. $temp_score_level_setting = $score_level_setting;
  125. if (isset($score_agent_goods_setting[$v['goods_id']])) $temp_score_level_setting = $score_agent_goods_setting[$v['goods_id']];
  126. }
  127. $team_prize_score = $agent_reward_obj->computing($temp_score_level_setting, $rules['money'], ComputingEnum::TEAM_PRIZE, $multiple);
  128. $team_prize_score = bcadd(0, $team_prize_score, 2);
  129. if($team_prize_score>0){
  130. $agent_deduct['score'] = $team_prize_score;
  131. $goods_extra = $form->sku[$v['goods_id']]['goods']['extra'];
  132. if(!empty($deduct_setting['score_deduct_ratio'])){
  133. $deduct_money = bcdiv($team_prize_score, $deduct_setting['score_deduct_ratio'], 2);
  134. }
  135. if($deduct_money>0){
  136. if($deduct_money>$v['goods_price']) $deduct_money = $v['goods_price'];
  137. $total_deduct_money += $deduct_money;
  138. $total_deduct_goods_price += $deduct_money;
  139. $total_deduct_money_temp += $deduct_money;
  140. $v['goods_price'] -= $deduct_money;
  141. $v['marketing']['agent_deduct'] += $deduct_money;
  142. $v['marketing']['pay_money'] = $v['goods_price'];
  143. }
  144. }
  145. }
  146. $v['marketing']['agent_extra'] = json_encode($agent_deduct);
  147. $row['goods_price'] -= bcadd(0, $total_deduct_money_temp, 2);
  148. }
  149. }
  150. $total_deduct_money = bcadd(0, $total_deduct_money, 2);
  151. $item['mch_order_info'] = $item['mch_order_info'] ?? [];
  152. $item['mch_order_info']['goods_price'] = $item['mch_order_info']['goods_price'] ?? 0;
  153. $item['mch_order_info']['goods_price'] -= $total_deduct_money;
  154. $form['group_order_goods'] = $group_order_goods;
  155. $form['total_pay_money'] -= $total_deduct_money;
  156. if (!empty($total_deduct_money) && $total_deduct_money > 0) $form->marketing['deduct']['agent_deduct'] = [
  157. 'name' => '经销商内购商品抵扣',
  158. 'money' => -floor($total_deduct_money * 100) / 100,
  159. 'agent_deduct'=>json_encode($agent_deduct)
  160. ];
  161. return $item;
  162. } catch (Exception $e) {
  163. self::setStaticError('经销商内购商品抵扣计算错误:' . $e->getMessage());
  164. return false;
  165. }
  166. }
  167. public static function getCommissionLevelSetting($mall_id, $agent_level, $name)
  168. {
  169. $agent_level_arr = AgentLevel::getOne([['mall_id' => $mall_id], ['level' => $agent_level], ['status' => StatusEnum::ENABLED]], true,
  170. ['commissionLevelSetting' => function ($query) use ($name,$mall_id,$agent_level) {
  171. $query->where(['commission_type' => $name])->andWhere(['mall_id'=>$mall_id,'level'=>$agent_level,'status' => StatusEnum::ENABLED])->select('id,mall_id,level,commission_type,from_type,is_percent_team,is_percent_equal,
  172. is_percent_over,is_percent_extra,agent_team_prize,agent_equal_prize,agent_over_prize,agent_extra_prize,status');
  173. }]);
  174. return $agent_level_arr['commissionLevelSetting'];
  175. }
  176. public static function getAgentGoodsSetting($mall_id,$goods, $name, $agent_level)
  177. {
  178. $goods_ids = array_column($goods, 'goods_id');
  179. $where = [['item_id' => $goods_ids, 'item_type' => 'goods', 'commission_type' => $name, 'status' => StatusEnum::ENABLED]];
  180. $select = 'id,mall_id,is_participate,is_enable,item_id,item_type,commission_type,is_percent_team,is_percent_equal,is_percent_over,is_percent_extra,status';
  181. $with = ['detail' => function ($query) use($agent_level,$mall_id){
  182. $query->where(['level'=>$agent_level,'mall_id'=>$mall_id,'status' => StatusEnum::ENABLED])->select('id,mall_id,agent_commission_item_setting_id,level,agent_team_prize,agent_equal_prize,agent_over_prize,agent_extra_prize,status');
  183. }];
  184. $agent_goods_setting_list = AgentCommissionItemSetting::lists(['where' => $where, 'with' => $with, 'select' => $select]);
  185. $setting_arr = [];
  186. if (!empty($agent_goods_setting_list)) {
  187. foreach ($agent_goods_setting_list as $agent_goods_setting) {
  188. if ($agent_goods_setting['commission_type'] == $name && $agent_goods_setting['is_enable']) {
  189. foreach ($agent_goods_setting['detail'] as $val) {
  190. if ($val['level'] == $agent_level) {
  191. $setting_arr[$agent_goods_setting['item_id']] = [
  192. 'is_percent_team' => $agent_goods_setting['is_percent_team'],
  193. 'is_percent_equal' => $agent_goods_setting['is_percent_equal'],
  194. 'is_percent_over' => $agent_goods_setting['is_percent_over'],
  195. 'is_percent_extra' => $agent_goods_setting['is_percent_extra'],
  196. 'agent_team_prize' => $val['agent_team_prize'],
  197. 'agent_equal_prize' => $val['agent_equal_prize'],
  198. 'agent_over_prize' => $val['agent_over_prize'],
  199. 'agent_extra_prize' => $val['agent_extra_prize'],
  200. ];
  201. }
  202. }
  203. }
  204. }
  205. }
  206. return $setting_arr;
  207. }
  208. public static function scoreProcessing($detail, $use_score, $goods_info)
  209. {
  210. $exc_money = 0;
  211. //获取积分商品抵扣比例
  212. $deduct_setting = \Yii::$app->services->setting->mall->get($detail['mall_id'], 'score');
  213. if ($deduct_setting['score_deduct_status'] == 1) {
  214. if ($goods_info) {
  215. if ($goods_info['score_deduct_setting']) {
  216. $setting = Json::decode($goods_info['score_deduct_setting']);
  217. //抵扣
  218. if ($setting['deduct_num'] > 0) {
  219. //1.单件抵扣 2.多件累计抵扣
  220. //单件抵扣,指该抵扣值可抵扣订单该商品1件,抵扣值如果大于商品售价则按商品售价计算
  221. //多件累计抵扣,指该抵扣值可抵扣订单内所有该商品,每件商品分摊此抵扣值
  222. if ($setting['deduct_type'] == 1) {
  223. //最大抵扣金额
  224. $max = bcdiv($detail['price'], $detail['num'], 2) > $setting['deduct_num'] ? $setting['deduct_num'] : bcdiv($detail['price'], $detail['num'], 2);
  225. } else {
  226. $max = $detail['price'] > $setting['deduct_num'] ? $setting['deduct_num'] : $detail['price'];
  227. }
  228. !empty($deduct_setting['score_deduct_ratio']) && $exc_money = bcdiv($use_score, $deduct_setting['score_deduct_ratio'], 2);
  229. if ($exc_money > 0) {
  230. if ($exc_money > $max) {
  231. $exc_money = $max;
  232. }
  233. }
  234. }
  235. }
  236. }
  237. }
  238. return $exc_money;
  239. }
  240. public static function getDeductMoney($mall_id,$user_id,$goods_attr_id_arr){
  241. $attr_id_arr = [];
  242. foreach ($goods_attr_id_arr as $goods_attr_id=>$num){
  243. $attr_id_arr[]=$goods_attr_id;
  244. }
  245. $params['where'] = [['=','status',StatusEnum::ENABLED],['id'=>$attr_id_arr]];
  246. $params['with'] = ['goods','goods.extra'];
  247. $sku_arr = \common\models\goods\GoodsAttr::lists($params,true);
  248. $order_goods_arr = [];
  249. foreach ($sku_arr as $sku){
  250. $buy_num = $goods_attr_id_arr[$sku['id']];
  251. $order_goods = new \common\models\order\OrderDetail();
  252. $order_goods = $order_goods->loadDefaultValues();
  253. $order_goods->goods_id = $sku['goods_id'];
  254. $order_goods->goods_name = $sku['goods']['goods_name'];
  255. $order_goods->goods_attr_id = $sku['id'];
  256. $order_goods->sign_id = $sku['sign_id'];
  257. $order_goods->goods_attr_name = $sku['name'];
  258. $order_goods->num = $buy_num;
  259. $order_goods->cost_price = $sku['cost_price'];
  260. $order_goods->price = $sku['price'];
  261. $order_goods->goods_price = bcmul($order_goods->num, $order_goods->price,2);
  262. $order_goods->original_goods_price = $order_goods->goods_price;
  263. $order_goods->pic_url = !empty($sku['pic_url']) ? $sku['pic_url'] : $sku['goods']['cover_pic'];
  264. $order_goods->user_id =$user_id;
  265. $order_goods->mch_id = $sku['goods']['mch_id'];
  266. $order_goods->mall_id = $mall_id;
  267. // 默认数据带下单数量方便计算
  268. $goods = $sku['goods'];
  269. $goods['number'] = $buy_num;
  270. $order_goods_arr[] = \common\helpers\ArrayHelper::toArray($order_goods);
  271. }
  272. // 产品按照商户重新归类组别
  273. $group_order_goods = [];
  274. foreach ($order_goods_arr as $item) {
  275. if (!isset($group_order_goods[$item['mch_id']]['goods'][$item['goods_id']])) {
  276. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['goods_id'] = $item['goods_id'];
  277. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['goods_price'] = 0;
  278. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['num'] = 0;
  279. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['goods_name'] = $item['goods_name'];
  280. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['goods_details'] = [];
  281. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['original_goods_price'] = 0;
  282. }
  283. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['goods_price'] += $item['goods_price'];
  284. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['original_goods_price'] += $item['original_goods_price'];
  285. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['num'] += $item['num'];
  286. $group_order_goods[$item['mch_id']]['goods'][$item['goods_id']]['goods_details'][] = $item;
  287. }
  288. $orderFormLogic = new \common\logic\order\OrderFormLogic();
  289. $form = $orderFormLogic->getDefaultform($mall_id, $user_id);
  290. $form->group_order_goods = $group_order_goods;
  291. $user = \common\models\user\User::getOne([['id'=>$user_id,'mall_id'=>$mall_id]]);
  292. $form->user = $user;
  293. $result = [];
  294. foreach ($group_order_goods as &$item) {
  295. $item = self::compute($item,$form,$extra);
  296. foreach ($item['goods'] ?? [] as $goods_id=>$val){
  297. foreach ($val['goods_details'] as $row){
  298. $row['marketing'] = $row['marketing'] ?? [];
  299. $row['marketing']['pay_money'] = $row['marketing']['pay_money'] ?? 0;
  300. $result[$row['goods_attr_id']] = $row['marketing']['pay_money'];
  301. }
  302. }
  303. }
  304. return $result;
  305. }
  306. }