AgentMarketing.php 20 KB

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