CommissionLogic.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <?php
  2. namespace addons\Community\common\logic;
  3. use addons\Community\common\enums\CommunityEnum;
  4. use addons\Community\common\enums\ConfigEnum;
  5. use addons\Community\common\models\CommunityGoodsModeSetting;
  6. use addons\Community\common\models\CommunityHead;
  7. use addons\Community\common\models\CommunityHeadCommission;
  8. use common\enums\AddonsEnum;
  9. use common\enums\OrderStatusEnum;
  10. use common\enums\StatusEnum;
  11. use common\helpers\FormatHelper;
  12. use common\models\mall\MallAddons;
  13. use common\models\order\Order;
  14. use common\models\order\OrderDetail;
  15. use services\common\UserWalletService;
  16. use Yii;
  17. use yii\db\Exception;
  18. use yii\helpers\Json;
  19. class CommissionLogic
  20. {
  21. public function exec(Order $order, array $config, array $ext)
  22. {
  23. $t = Yii::$app->db->beginTransaction();
  24. try {
  25. $this->execMain($order, $config, $ext);
  26. $t->commit();
  27. } catch (\Exception $e) {
  28. $t->rollBack();
  29. $exception = FormatHelper::exception($e, "订单支付触发社区团购插件事件: 分润失败 {$order->id} " . Json::encode($ext) . " " . Json::encode($config));
  30. Yii::error($exception);
  31. }
  32. }
  33. /**
  34. * @throws Exception
  35. */
  36. public function execMain(Order $order, array $config, array $ext)
  37. {
  38. $mall_id = $order['mall_id'];
  39. $order_id = $order['id'];
  40. $user_id = $order['user_id'];
  41. $head_user_id = CommunityHead::find()
  42. ->where(['mall_id' => $mall_id])
  43. ->andWhere(['id' => $ext['head_id']])
  44. // ->andWhere(['status' => StatusEnum::ENABLED]) // 有可能中途被删除
  45. ->andWhere(['check_status' => StatusEnum::ENABLED])
  46. ->select('user_id')->scalar();
  47. if (empty($head_user_id)) {
  48. Yii::error("团长不存在: {$ext['head_id']}");
  49. return false;
  50. }
  51. $params['where'] = [['order_id' => $order_id], ['user_id' => $user_id], ['mall_id' => $mall_id], ['order_status' => $order->order_status]];
  52. $order_detail_list = OrderDetail::lists($params);
  53. if (empty($order_detail_list)) {
  54. Yii::error("订单详情不存在: {$order_id}");
  55. return false;
  56. }
  57. $insert_wallet = [];
  58. $insert_plugin = [];
  59. foreach ($order_detail_list as $item) {
  60. $modes = CommunityGoodsModeSetting::lists([
  61. 'where' => [
  62. ['item_id' => $item['goods_id']],
  63. ['enable' => StatusEnum::ENABLED],
  64. ['status' => StatusEnum::ENABLED],
  65. ]
  66. ]);
  67. $calc_commission = 0;
  68. $commission = 0;
  69. $score = 0;
  70. $hi_bei = 0;
  71. $hi_value = 0;
  72. if (!empty($modes)) {
  73. foreach ($modes as $mode) {
  74. if ($mode['is_alone'] == StatusEnum::ENABLED) { // 单独设置
  75. if ($mode['give_num'] <= 0) continue; // 奖励为0的则不赠送
  76. switch ($mode['commission_type']) {
  77. case 'commission': // 佣金
  78. $commission = bcmul($mode['give_num'], $item['num'], 2);
  79. if ($mode['is_percent'] == StatusEnum::DISABLED) { // 这里是百分比
  80. $commission = bcmul($item['goods_price'], bcmul($mode['give_num'], 0.01, 2), 2);
  81. }
  82. Yii::error("{$order['order_no']} commission {$commission} - {$mode['is_percent']} - {$item['goods_price']}");
  83. break;
  84. case 'score': // 积分
  85. $score = bcmul($mode['give_num'], $item['num'], 2);
  86. if ($mode['is_percent'] == StatusEnum::DISABLED) { // 这里是百分比
  87. $score = bcmul($item['goods_price'], bcmul($mode['give_num'], 0.01, 2), 2);
  88. }
  89. break;
  90. case 'hi_bei': // 嗨呗
  91. // 判断有没有安装这个插件
  92. if (MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_HI_GO)) {
  93. $hi_bei = bcmul($mode['give_num'], $item['num'], 2);
  94. if ($mode['is_percent'] == StatusEnum::DISABLED) { // 这里是百分比
  95. $hi_bei = bcmul($item['goods_price'], bcmul($mode['give_num'], 0.01, 2), 2);
  96. }
  97. }
  98. break;
  99. case 'hi_value': // 嗨值
  100. // 判断有没有安装过这个插件
  101. if (MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_HI_GO)) {
  102. $hi_value = bcmul($mode['give_num'], $item['num'], 2);
  103. if ($mode['is_percent'] == StatusEnum::DISABLED) { // 这里是百分比
  104. $hi_value = bcmul($item['goods_price'], bcmul($mode['give_num'], 0.01, 2), 2);
  105. }
  106. }
  107. break;
  108. }
  109. switch ($mode['commission_type']) {
  110. case 'commission': // 默认就是这个
  111. $commission = $commission;
  112. break;
  113. case 'score':
  114. $score = $score;
  115. break;
  116. case 'hi_bei':
  117. $hi_bei = $hi_bei;
  118. break;
  119. case 'hi_value':
  120. $hi_value = $hi_value;
  121. break;
  122. }
  123. Yii::$app->custom->logs("{$order['order_no']} {$mode['item_id']} - {$mode['commission_type']} - {$mode['is_alone']} - {$mode['give_num']} - {$item['goods_price']} - {$commission}");
  124. } else {
  125. // 这边只有余额?
  126. if ($config['is_enable_reward'] == StatusEnum::DISABLED) {
  127. Yii::error("Community reward 未开启奖励");
  128. continue;
  129. } // 未开启团长奖励
  130. switch ($config['head_commission_type']) {
  131. case ConfigEnum::HEAD_COMMISSION_TYPE_FIXED: // 固定金额
  132. $calc_commission = bcmul($config['commission'], $item['num'], 2);
  133. break;
  134. case ConfigEnum::HEAD_COMMISSION_TYPE_RATE: // 百分比
  135. $base_amount = 0;
  136. switch ($config['calculate_type']) {
  137. case ConfigEnum::CALCULATE_TYPE_PAY_AMOUNT: // 实际支付金额
  138. $base_amount = $item['goods_price']; // 已经包含数量
  139. break;
  140. case ConfigEnum::CALCULATE_TYPE_GOODS_PRICE: // 商品售价
  141. // 计算商品售价
  142. $base_amount = bcmul($item['price'], $item['num'], 2);
  143. break;
  144. case ConfigEnum::CALCULATE_TYPE_GOODS_PROFIT: // 商品利润
  145. $base_amount = bcmul(bcsub($item['price'], $item['cost_price'], 2), $item['num'], 2);
  146. break;
  147. }
  148. $calc_commission = bcmul($base_amount, bcmul($config['commission'], 0.01, 2), 2);
  149. break;
  150. }
  151. // 默认就是这个
  152. $commission = $calc_commission;
  153. Yii::$app->custom->logs("{$order['order_no']} - {$commission}");
  154. }
  155. }
  156. } else {
  157. // 这边只有余额?
  158. if ($config['is_enable_reward'] == StatusEnum::DISABLED) {
  159. Yii::error("Community reward 未开启奖励");
  160. continue;
  161. } // 未开启团长奖励
  162. switch ($config['head_commission_type']) {
  163. case ConfigEnum::HEAD_COMMISSION_TYPE_FIXED: // 固定金额
  164. $calc_commission = bcmul($config['commission'], $item['num'], 2);
  165. break;
  166. case ConfigEnum::HEAD_COMMISSION_TYPE_RATE: // 百分比
  167. $base_amount = 0;
  168. switch ($config['calculate_type']) {
  169. case ConfigEnum::CALCULATE_TYPE_PAY_AMOUNT: // 实际支付金额
  170. $base_amount = $item['goods_price']; // 已经包含数量
  171. break;
  172. case ConfigEnum::CALCULATE_TYPE_GOODS_PRICE: // 商品售价
  173. // 计算商品售价
  174. $base_amount = bcmul($item['price'], $item['num'], 2);
  175. break;
  176. case ConfigEnum::CALCULATE_TYPE_GOODS_PROFIT: // 商品利润
  177. $base_amount = bcmul(bcsub($item['price'], $item['cost_price'], 2), $item['num'], 2);
  178. break;
  179. }
  180. $calc_commission = bcmul($base_amount, bcmul($config['commission'], 0.01, 2), 2);
  181. break;
  182. }
  183. // 默认就是这个
  184. $commission = $calc_commission;
  185. Yii::$app->custom->logs("{$order['order_no']} - {$commission}");
  186. }
  187. $wallet_main = [
  188. 'mall_id' => $mall_id,
  189. 'user_id' => $head_user_id,
  190. 'is_frozen' => false,
  191. 'source_table' => OrderDetail::tableName(),
  192. 'source_table_id' => $item['id'], // 取出订单ID?
  193. 'from_type' => CommunityEnum::ADDONS_NAME,
  194. 'capital_type' => CommunityEnum::COMMUNITY_PICKUP_PRIZE,
  195. 'contributor_name' => '',
  196. 'order_no' => $order['order_no'], // 这里需要订单号
  197. ];
  198. $plugin_main = [
  199. 'mall_id' => $mall_id,
  200. 'user_id' => $head_user_id, // 获奖用户 - 团长用户ID
  201. 'head_id' => $ext['head_id'],
  202. 'order_id' => $order['id'],
  203. 'buyer_user_id' => $user_id,
  204. 'created_at'=> time(),
  205. 'updated_at'=> time(),
  206. ];
  207. // 添加到冻结金额
  208. if (!empty($commission) && $commission > 0) {
  209. Yii::error("{$order['order_no']} {$item['goods_id']} -- {$commission}");
  210. $wallet_main['wallet_type'] = UserWalletService::WALLET_TYPE_COMMISSION;
  211. $wallet_main['money'] = $commission;
  212. $wallet_main['desc'] = "用户 ({$user_id}) ,获得自提订单 ({$order['id']}) 奖励, 奖励类型:(佣金), 共奖励 ({$commission}) 元佣金";
  213. $insert_wallet[] = $wallet_main;
  214. $plugin_main['intro'] = "用户ID为[{$user_id}]的自提人完成订单编号为[{$order['order_no']}]的订单获得提成";
  215. $plugin_main['commission'] = bcmul($commission, 100);
  216. $plugin_main['reward_type'] = ConfigEnum::COMMUNITY_REWARD_TYPE_COMMISSION;
  217. $insert_plugin[] = $plugin_main;
  218. }
  219. if (!empty($score) && $score > 0) {
  220. Yii::error("{$order['order_no']} {$item['goods_id']} -- {$score}");
  221. $wallet_main['wallet_type'] = UserWalletService::WALLET_TYPE_SCORE;
  222. $wallet_main['money'] = $score;
  223. $wallet_main['desc'] = "用户 ({$user_id}) ,获得自提订单 ({$order['id']}) 奖励, 奖励类型:(积分), 共奖励 ({$score}) 积分";
  224. $insert_wallet[] = $wallet_main;
  225. $plugin_main['intro'] = "用户ID为[{$user_id}]的自提人完成订单编号为[{$order['order_no']}]的订单获得提成";
  226. $plugin_main['commission'] = bcmul($score, 100);
  227. $plugin_main['reward_type'] = ConfigEnum::COMMUNITY_REWARD_TYPE_SCORE;
  228. $insert_plugin[] = $plugin_main;
  229. }
  230. // 嗨呗/嗨值暂时不写
  231. if (!empty($hi_bei) && $hi_bei > 0) {
  232. // $plugin_main['intro'] = "用户ID为[{$user_id}]的自提人完成订单编号为[{$order['order_no']}]的订单获得提成";
  233. // $plugin_main['commission'] = $hi_bei;
  234. // $plugin_main['reward_type'] = ConfigEnum::COMMUNITY_REWARD_TYPE_HI_BEI;
  235. // $insert_plugin[] = $plugin_main;
  236. }
  237. if (!empty($hi_value) && $hi_value > 0) {
  238. // $plugin_main['intro'] = "用户ID为[{$user_id}]的自提人完成订单编号为[{$order['order_no']}]的订单获得提成";
  239. // $plugin_main['commission'] = $hi_value;
  240. // $plugin_main['reward_type'] = ConfigEnum::COMMUNITY_REWARD_TYPE_HI_VALUE;
  241. // $insert_plugin[] = $plugin_main;
  242. }
  243. }
  244. if (!empty($insert_wallet)) { // 不为空的情况下
  245. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  246. if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
  247. }
  248. if (!empty($higo_wallet_insert)) { // higo新增数据
  249. }
  250. if (!empty($insert_plugin)) {
  251. Yii::error("insert_plugin: " . Json::encode($insert_plugin));
  252. // 写入记录
  253. Yii::$app->db->createCommand()->batchInsert(CommunityHeadCommission::tableName(), array_keys($insert_plugin[0]), $insert_plugin)->execute();
  254. }
  255. return true;
  256. }
  257. /**
  258. * 佣金退回
  259. * @param array $commission_list
  260. * @param array $score_list
  261. * @return void
  262. */
  263. public function refund(array $commission_list, array $score_list)
  264. {
  265. /*
  266. $t = Yii::$app->db->beginTransaction();
  267. try {
  268. $order_no = !empty($commission_list) ? $commission_list[0]['order_no'] : $score_list[0]['order_no'];
  269. if (empty($order_no)) throw new \Exception('没有订单编号');
  270. $order = Order::find()->where(['order_no' => $order_no])->one();
  271. if (empty($order)) throw new \Exception('订单不存在');
  272. // 获取团长信息
  273. if ($order->shipping_type == OrderStatusEnum::SHIPMENTS && !empty($order->extra_info)) { // 如果是自提订单
  274. $ext = Json::decode($order->extra_info);
  275. if (empty($ext['head_id'])) {
  276. throw new \Exception("OrderPaidRewardListener 非站点自提订单: {$order->id}");
  277. }
  278. }
  279. $insert_wallet = [];
  280. $insert_plugin = [];
  281. $wallet_main = [
  282. 'mall_id' => $order->mall_id,
  283. 'user_id' => $user_id,
  284. 'is_frozen' => false,
  285. 'source_table' => OrderDetail::tableName(),
  286. 'source_table_id' => $item['id'], // 取出订单ID?
  287. 'from_type' => CommunityEnum::ADDONS_NAME,
  288. 'capital_type' => CommunityEnum::COMMUNITY_PICKUP_PRIZE,
  289. 'contributor_name' => '',
  290. 'order_no' => $order['order_no'], // 这里需要订单号
  291. ];
  292. $plugin_main = [
  293. 'mall_id' => $mall_id,
  294. 'user_id' => $head_user_id, // 获奖用户 - 团长用户ID
  295. 'head_id' => $ext['head_id'],
  296. 'order_id' => $order['id'],
  297. 'buyer_user_id' => $user_id,
  298. 'is_inflow' => StatusEnum::DISABLED, // 非流入
  299. ];
  300. // order_no
  301. if (!empty($commission_list)) {
  302. foreach ($commission_list as $item) {
  303. }
  304. }
  305. if (!empty($score_list)) {
  306. foreach ($score_list as $item) {
  307. }
  308. }
  309. $t->commit();
  310. } catch (\Exception $e) {
  311. $t->rollBack();
  312. $exception = FormatHelper::exception($e, "社区团购退回佣金失败");
  313. \Yii::error($exception);
  314. }
  315. */
  316. }
  317. }