| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808 |
- <?php
- namespace addons\ServeBonus\common\logic;
- use addons\ServeBonus\common\enums\ServeBonusEnum;
- use addons\ServeBonus\common\models\ServeBonus;
- use addons\ServeBonus\common\models\ServeBonusCommissionItemSetting;
- use addons\ServeBonus\common\models\ServeBonusAchievement;
- use addons\ServeBonus\common\models\ServeBonusLevelSetting;
- use addons\ServeBonus\common\models\ServeBonusRewardLog;
- use addons\ServeBonus\common\models\ServeBonusOrderLog;
- use addons\ServeBonus\common\models\ServeBonusAchievementSettleLog;
- use addons\ServeBonus\common\models\ServeBonusCloudStockPeriod;
- use addons\CloudStock\common\enums\CloudStockEnum;
- use addons\CloudStock\common\models\CloudStockBuyingOrder;
- use addons\CloudStock\common\models\CloudStockFillOrder;
- use addons\CloudStock\common\models\CloudStockAgent;
- use addons\CloudStock\common\models\CloudStockGoods;
- use addons\CloudStock\common\models\CloudStockUpgradeBag;
- use addons\ServeBonus\common\models\ServeBonusLevel;
- use common\models\goods\Goods;
- use common\models\order\Order;
- use common\enums\StatusEnum;
- use common\helpers\ArrayHelper;
- use common\helpers\FormatHelper;
- use common\models\common\CapitalLog;
- use common\models\common\CommissionLog;
- use common\models\mall\MallAddons;
- use common\models\user\User;
- use yii\helpers\Json;
- use common\models\order\OrderDetail;
- use common\models\user\UserTeamMonthStatistics;
- use common\traits\ErrorTrait;
- use Exception;
- use yii;
- /**
- * Class RewardLog
- * @Author: ltm
- * @DateTime: 2021/10/25 9:39
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @package addons\ServeBonus\common\logic
- */
- class RewardLogLogic
- {
- use ErrorTrait;
- /**
- * @Author: hua
- * @DateTime: 2021/10/18 9:57
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $data
- * @return bool
- */
- public function execute($order, $settlement_method)
- {
- try {
- // 查询订单信息
- $where['where'] = [['=', 'order_id', $order['id']], ['=', 'status', StatusEnum::ENABLED]];
- $order_detail = OrderDetail::lists($where, true);
- if (empty($order_detail)) return true;
- // 初始化数据
- $mallId = $order['mall_id'];
- $user_id = $order['user_id'];
- $calculate = [];// 佣金计算
- $amounts = 0;// 结算的总金额
- $date = date('Ymd', time());
- $time = time();
- // 判断用户插件是否安装
- if (MallAddons::isInstall($mallId, ServeBonusEnum::ADDONS_NAME) == false) return true;
- // 获取基础配置
- $config = Yii::$app->services->setting->addons->get($mallId, 'ServeBonus', 'basic');
- // 判断是否开启插件分润
- if ($config['is_enable'] == StatusEnum::DISABLED) return true;
- // 判断结算方式,0=支付完成,1=订单完成
- if ($config['settlement_method'] != $settlement_method) return true;
- // 获取用户信息
- $user = User::find()->select("parent_id")->where(['id' => $user_id, 'status' => StatusEnum::ENABLED])->asArray()->one();
- $parent_level = ServeBonus::find()->select("level")->where(['mall_id' => $mallId,'user_id' => $user['parent_id'], 'status' => StatusEnum::ENABLED])->asArray()->scalar();
- // 获取服务商等级列表
- $field = 'level,prize,is_percent_prize,extra_prize,is_percent_extra,is_extra,extra_type,extra_is_limit,extra_limit_price,is_accumulation,is_cloud_stock_open,accumulation_condition,accumulation_condition_money';
- $level_arr = ServeBonusLevelSetting::find()->select($field)->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])->orderBy('level asc')->asArray()->all();
- if (empty($level_arr)) return true;
- $level_arr = array_column($level_arr, null, 'level');
- // 获取所有服务商列表
- $servebonus_list = ServeBonus::find()->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])->all();
- if (empty($servebonus_list)) return true;
- // 服务商是否开启加权平均分限制条件
- $last_month = date('Y-m', strtotime('-1 month'));
- $unachievement_list = [];
- $achievement_field = $config['achievement_count_method'] == 1 ? 'finish_price' : 'price';
- //排除已经达到佣金上限的服务商
- $level_list = [];
- $diff_num = [];
- foreach ($servebonus_list as $lv => $slb) {
- $level = null;
- if (!isset($level_list[$slb->level])) {
- $level = ServeBonusLevel::find()->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED, 'level' => $slb->level])->one();
- if ($level) {
- $level_list[$slb->level] = $level;
- } else {
- $level_list[$slb->level] = null;
- }
- } else {
- $level = $level_list[$slb->level];
- }
- if (!$level) unset($servebonus_list[$lv]);
- //计算金额
- if ($level->is_to_bonus && $level->to_bonus_price > 0) {
- CapitalLog::$capitalType = 'commission';
- $total_settled = CapitalLog::find()->where(['user_id' => $slb->user_id, 'change_type' => 'add'])->sum('change_num') ?? 0;
- CapitalLog::$capitalType = 'commission_frozen';
- $total_nosettled = CapitalLog::find()->where(['user_id' => $slb->user_id, 'change_type' => 'add'])->sum('change_num') ?? 0;
- $total = bcadd($total_nosettled + $total_settled, 2);
- if ($total >= $level->to_bonus_price) {
- unset($servebonus_list[$lv]);
- $diff_num[$slb->level] += 1;
- }
- }
- // 加权平均分限制条件
- if ($level_arr[$slb->level]['accumulation_condition'] == 1) {
- $achievement_price = UserTeamMonthStatistics::find()->where(['mall_id' => $mallId, 'user_id' => $slb->user_id, 'month' => $last_month, 'status' => StatusEnum::ENABLED])->select($achievement_field)->scalar();
- // 加权平均分限制条件,上月团队总业绩需达标
- if ($achievement_price < $level_arr[$slb->level]['accumulation_condition_money']) {
- $diff_num[$slb->level] += 1;
- $unachievement_list[] = $slb->id;
- }
- }
- }
- // 统计各个服务商等级的总人数
- $level_count = ServeBonus::find()
- ->select("count(id) num,level")
- ->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])
- ->groupBy("level")
- ->indexBy("level")
- ->orderBy("level asc")
- ->asArray()
- ->all();
- //减去相应的人头
- if ($level_count) {
- foreach ($level_count as &$lv_item) {
- if (isset($diff_num[$lv_item['level']])) {
- $lv_item['num'] = $lv_item['num'] - $diff_num[$lv_item['level']];
- if ($lv_item['num'] < 0) $lv_item['num'] = 0;
- }
- }
- }
- $temp_level_count = $level_count;
-
- $settlement_data = [];
- $total_commonisson = 0;// 出单奖励总奖励金额初始化
- // 循环订单详情,对不同商品进行对应的佣金结算
- foreach ($order_detail as $index => $detail) {
- $accumulation_num = $prev_commission = 0;// 叠加数量,叠加奖励;
- // 查询服务商商品
- $goods_setting = ServeBonusCommissionItemSetting::getOne([['mall_id' => $mallId,'item_id' => $detail['goods_id'], 'is_enable' => StatusEnum::ENABLED]], true, ['detail']);
- if (empty($goods_setting)) continue;
- //新增:云库存商品判断
- if(!empty($config['is_cloud_stock_open'])){
- $cloud_stock_goods = CloudStockGoods::findOne(['mall_id'=>$mallId,'goods_id'=>$detail['goods_id'],'status' => StatusEnum::ENABLED]);
- $upgrade_bag_list = CloudStockUpgradeBag::lists(['where'=>['mall_id'=>$mallId,'status' => StatusEnum::ENABLED]]);
- $is_upgrade_bag_goods = false;
- foreach($upgrade_bag_list as $upgrade_bag){
- $upgrade_bag_goods = is_numeric($upgrade_bag['goods_id']) ? [$upgrade_bag['goods_id']] : json_decode($upgrade_bag['goods_id'],true);
- if(in_array($detail['goods_id'],$upgrade_bag_goods)){
- $is_upgrade_bag_goods = true;
- break;
- }
- }
- if(!empty($cloud_stock_goods) || $is_upgrade_bag_goods) continue;
- }
- // 获取结算的金额
- if ($config['compute_type'] == 0) $order_money = $detail['goods_price'];// 支付金额
- if ($config['compute_type'] == 1) $order_money = $detail['goods_price'] - ($detail['cost_price'] * $detail['num']) + $detail['adjust_money'];// 商品利润
- if ($config['compute_type'] == 2) $order_money = $detail['price'] * $detail['num'];// 商品售价
- if ($order_money <= 0) continue;// 分红金额过小则没必要分红
- //添加订单记录
- $order_log = ServeBonusOrderLog::findOne(['order_no'=>$order['order_no'],'order_detail_id'=>$detail['id']]);
- if(empty($order_log)){
- $order_log_params = [
- 'mall_id'=> $mallId,
- 'order_id' => $order['id'],
- 'order_detail_id' => $detail['id'],
- 'order_no' => $order['order_no'],
- 'order_type' => 0,
- 'money' => $order_money,
- 'date' => $date,
- 'goods_id' => $detail['goods_id'],
- 'num' => (int)$detail['num'],
- ];
- $res = ServeBonusOrderLog::setData($order_log_params);
- if ($res == false) throw new Exception(ServeBonusOrderLog::getStaticError());
- }
- $amounts = $amounts + $order_money;
- // 判断是否开启独立设置
- $is_gooods_alone = false;
- if (!empty($goods_setting['is_alone']) && $goods_setting['is_alone'] == 1) {
- // 商品独立分佣配置
- $level_calculate = $goods_setting['detail'];
- $is_gooods_alone = true;
- } else {
- // 等级分佣配置
- $level_calculate = $level_arr;
- }
- // 将等级设计倒叙,最高等级为排第一,计算各个等级开启叠加分红后的数量
- $level_count = $temp_level_count;
- $desc_level_calculate = ArrayHelper::arraySort($level_calculate, 'level', 'desc');
- foreach ($desc_level_calculate as $level) {
- $level_num = $level_count[$level['level']]['num'];// 该等级的人数
- $level_count[$level['level']]['num'] += $accumulation_num;// 统计的人数 = 等级人数 + 开启叠加分红等级人数
- // 判断是否开启叠加分红,开启叠加分红则增加对应的等级人数
- if ($level['is_accumulation'] == StatusEnum::ENABLED) {
- $accumulation_num += $level_num;
- }
- }
- // 对应的等级的出单奖励/加权分红计算
- foreach ($level_calculate as &$level) {
- $level_num = $level_count[$level['level']]['num'];// 统计的人数
- if ($level_num <= 0) {
- $extra_commonisson = 0;
- } else {
- if ($is_gooods_alone) {// 商品独立设置
- $level['is_percent_extra'] = $goods_setting['is_percent_extra'];
- $level['is_percent_prize'] = $goods_setting['is_percent_prize'];
- }
- if ($level['is_percent_extra'] == 0) {// 百分比
- $extra_commonisson = $level['extra_prize'] ? bcdiv($order_money * $level['extra_prize'] / $level_num, 100, 2) : 0;// 加权分红,单位:元
- $amounts = $order_money;
- } else {// 固定金额
- $extra_commonisson = $level['extra_prize'] ? bcdiv(($detail['num'] * $level['extra_prize']), $level_num, 2) : 0;// 加权分红,单位:元
- $amounts = ($detail['num'] * $level['extra_prize']);
- }
- // 出单奖励金额计算
- if ($level['level'] == $parent_level) {
- if ($level['is_percent_prize'] == 0) {// 百分比
- $total_commonisson += $level['prize'] ? bcdiv($order_money * $level['prize'], 100, 2) : 0;// 加权分红,单位:元
- } else {// 固定金额
- $total_commonisson += ($detail['num'] * $level['prize']);// 出单奖励,单位:元
- }
- }
- }
- $total_extra_commonisson = $level['is_accumulation'] == StatusEnum::ENABLED ? $extra_commonisson + $prev_commission : $extra_commonisson;
- // 单个商品的结算明细
- $settlement_data[$level['level']][] = [
- 'detail_id' => $detail['id'],
- 'goods_id' => $detail['goods_id'],
- 'goods_name' => $detail['goods_name'],
- 'amounts' => $amounts,
- 'prize' => 0,
- 'commonisson' => 0,
- 'is_accumulation' => $level['is_accumulation'],
- 'average_count' => $level_num,
- 'accumulation_prize' => $prev_commission,
- 'is_percent_extra' => $level['is_percent_extra'],
- 'extra_prize' => $level['extra_prize'],
- 'extra_commonisson' => $total_extra_commonisson,
- ];
- // 分红佣金计算
- $calculate[$level['level']] = [
- 'commission' => 0,
- 'extra_commission' => empty($calculate[$level['level']]['extra_commission']) ? $total_extra_commonisson : $calculate[$level['level']]['extra_commission'] + $total_extra_commonisson,
- 'settlement_data' => $settlement_data[$level['level']],
- ];
- $prev_commission += $extra_commonisson;// 低层级叠加的佣金
- }
- }
- // 结算的配置
- $settlement_config = [
- 'compute_type' => $config['compute_type'],// 佣金计算方式
- 'settlement_method' => $config['settlement_method'],// 结算方式
- ];
- // 分红计算
- foreach ($servebonus_list as $servebonus) {
- if (empty($calculate[$servebonus->level])) continue;
- // 判断用户是否符合额外分红条件
- if ($level[$servebonus->level]['extra_type'] == 1 && $servebonus->upgrade_status != 1) continue;
- if ($level[$servebonus->level]['extra_type'] == 2 && $servebonus->upgrade_status != 2) continue;
- // 不达标则跳过
- if (!in_array($servebonus->id, $unachievement_list)) {
- $extra_settlement_config = $settlement_config;
- $extra_commission = $calculate[$servebonus->level]['extra_commission'];
- // 判断是否设置额外分红上限并且用户是否达到额外分红上限
- if ($level_arr[$servebonus->level]['extra_is_limit'] == 1) {
- // 已超额则直接退出
- if ($servebonus->temp_extra_commission > $level_arr[$servebonus->level]['extra_limit_price']) continue;
-
- // 没超额,但是加上奖励金额则超额,额外分红 = 限制金额 - 已有额外金额;
- if ($servebonus->temp_extra_commission + $calculate[$servebonus->level]['extra_commission'] > $level_arr[$servebonus->level]['extra_limit_price']) {
- $extra_commission = $level_arr[$servebonus->level]['extra_limit_price'] - $servebonus->temp_extra_commission;
- $extra_settlement_config['extra_msg'] = '额外分红金额已达到上限,应得额外分红:¥' . $calculate[$servebonus->level]['extra_commission'] . ',实得额外分红:¥' . $extra_commission;
- }
- }
-
- // 额外分红
- $extra_commission > 0 && $rows[] = [
- 'mall_id' => $servebonus->mall_id,
- 'order_id' => $order['id'],
- 'order_no' => $order['order_no'],
- 'user_id' => $servebonus->user_id,
- 'type' => 2,
- 'level' => $servebonus->level,// 服务商等级
- 'amounts' => $calculate[$servebonus->level]['settlement_data'][0]['amounts'],
- 'commission' => $extra_commission,
- 'settlement_config' => Json::encode($extra_settlement_config),
- 'settlement_data' => Json::encode($calculate[$servebonus->level]['settlement_data']),
- 'date' => $date,
- 'created_at' => $time,
- 'updated_at' => $time,
- ];
- // 增加额外分红的临时额度
- $servebonus->temp_extra_commission += $calculate[$servebonus->level]['extra_commission'];
- $servebonus->save();
- }
- // 计算出单奖励金额
- if (!empty($user['parent_id']) && $user['parent_id'] == $servebonus->user_id) {
- $parent_level = $servebonus->level;
- $commonisson = $total_commonisson;// 出单奖励,单位:元
- }
- }
- // 保存数据
- if (!empty($rows)) {
- $trans = Yii::$app->db->beginTransaction();
- try {
- // 今日出单记录
- if (!empty($user['parent_id']) && !empty($commonisson)) {
- $achievement = ['mall_id' => $mallId, 'user_id' => $user['parent_id'], 'buy_uid' => $user_id, 'level' => $parent_level, 'order_id' => $order['id'], 'order_no' => $order['order_no'], 'prize' => $commonisson, 'date' => $date];
- $res = ServeBonusAchievement::setData($achievement);
- if ($res == false) throw new Exception(ServeBonusAchievement::getStaticError());
- }
- // 生成数据
- $field = ['mall_id','order_id','order_no','user_id','type','level','amounts','commission','settlement_config','settlement_data','date','created_at','updated_at'];
- $res = Yii::$app->db->createCommand()->batchInsert(ServeBonusRewardLog::tableName(), $field, $rows)->execute();
- if ($res == false) throw new Exception(ServeBonusRewardLog::getStaticError());
- $trans->commit();
- } catch (Exception $e) {
- $trans->rollBack();
- $this->setError($e->getMessage());
- return false;
- }
- }
- return true;
- } catch (Exception $e) {
- $exception = FormatHelper::exception($e, '订单触发服务商分红计算错误');
- echo $exception;
- $this->setError($exception);
- return false;
- }
- }
- public function executeByCloudStock($order){
- try{
- // 初始化数据
- $mallId = $order['mall_id'];
- $user_id = 0;
- $order_id = 0;
- $order_no = '';
- $calculate = [];// 佣金计算
- $amounts = 0;// 结算的总金额
- $date = date('Ymd', time());
- $time = time();
- // 获取基础配置
- $config = Yii::$app->services->setting->addons->get($mallId, 'ServeBonus', 'basic');
- // 判断是否开启插件分润
- if ($config['is_enable'] == StatusEnum::DISABLED) return true;
- //新增:云库存商品判断
- if(empty($config['is_cloud_stock_open'])) return false;
- $order_detail = [];
- $from_order = [];
- //升级礼包
- if($order['changes_type'] == CloudStockEnum::CHANGE_TYPE_INCREASE_UPGRADE_BAG_GIVE){
- // 查询订单信息
- $configs = \Yii::$app->services->setting->addons->get($mallId, \common\enums\AddonsEnum::ADDONS_NAME_CLOUD_STOCK, 'basic');
- $level_up_give_stock_by_parent_type = $configs['level_up_give_stock_by_parent_type'] ?? 0;
- if($level_up_give_stock_by_parent_type == 1){
- $cloud_stock_fill_order_relation = \addons\CloudStock\common\models\CloudStockFillOrderRelation::findOne(['fill_order_id'=>$order['order_id']]);
- if(empty($cloud_stock_fill_order_relation)) return true;
- $order['order_id'] = $cloud_stock_fill_order_relation['order_id'];
- }
- $where['where'] = [['=', 'order_id', $order['order_id']], ['=', 'status', StatusEnum::ENABLED]];
- $order_detail = OrderDetail::lists($where, true);
- if (empty($order_detail)) return true;
- // $goods = Goods::findOne($order['goods_id']);
- // $order_detail[] = [
- // 'goods_price' => $goods['price'] * $order['num'],
- // 'goods_id' => $order['goods_id'],
- // 'num' => $order['num'],
- // 'cost_price' => $goods['cost_price'],
- // 'adjust_money' => 0,
- // 'price' => $goods['price'],
- // ];
- $user_id = $order_detail[0]['user_id'];
- $from_order = Order::findOne($order['order_id']);
- if(empty($from_order)) return true;
- }elseif($order['order_type'] == CloudStockEnum::STOCK_ORDER_TYPE_USER){
- $buying_order = CloudStockBuyingOrder::findOne($order['order_id']);
- // 查询订单信息
- $where['where'] = [['=', 'id', $buying_order['order_detail_id']]];
- $order_detail = OrderDetail::lists($where, true);
- if (empty($order_detail)) return true;
- $user_id = $buying_order['user_id'];
- $from_order = Order::findOne($buying_order['order_id']);
- if(empty($from_order)) return true;
- }elseif($order['order_type'] == CloudStockEnum::STOCK_ORDER_TYPE_REPLENISH){
- $fill_order = CloudStockFillOrder::findOne($order['order_id']);
- if (empty($fill_order)) return true;
- $goods = Goods::findOne($fill_order['goods_id']);
- $order_detail[] = [
- 'goods_price' => $fill_order['pay_money'],
- 'goods_id' => $fill_order['goods_id'],
- 'num' => $fill_order['num'],
- 'cost_price' => $goods['cost_price'],
- 'adjust_money' => 0,
- 'price' => $goods['price'],
- ];
- $user_id = $fill_order['user_id'];
- $from_order = $fill_order;
- if(empty($from_order)) return true;
- }else{
- return true;
- }
- //不是升级礼包商品 根据扣除平台数量计算
- if($order['changes_type'] != CloudStockEnum::CHANGE_TYPE_INCREASE_UPGRADE_BAG_GIVE){
- foreach($order_detail as &$detail){
- $detail['num'] = $order['num'];
- }
- }
- // 获取用户信息
- $user = User::find()->select("parent_id")->where(['id' => $user_id, 'status' => StatusEnum::ENABLED])->asArray()->one();
- $parent_level = ServeBonus::find()->select("level")->where(['mall_id' => $mallId,'user_id' => $user['parent_id'], 'status' => StatusEnum::ENABLED])->asArray()->scalar();
- // 获取服务商等级列表
- $field = 'level,prize,is_percent_prize,extra_prize,is_percent_extra,is_extra,extra_type,extra_is_limit,extra_limit_price,is_accumulation,is_cloud_stock_open,cloud_stock_achievement_percent,cloud_stock_achievement_prize,accumulation_condition,accumulation_condition_money';
- $level_arr = ServeBonusLevelSetting::find()->select($field)->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])->orderBy('level asc')->asArray()->all();
- if (empty($level_arr)) return true;
- $level_arr = array_column($level_arr, null, 'level');
- // 获取所有服务商列表
- $servebonus_list = ServeBonus::find()->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])->all();
- if (empty($servebonus_list)) return true;
- //排除已经达到佣金上限的服务商
- $level_list = [];
- $diff_num = [];
- foreach ($servebonus_list as $lv => $slb) {
- $level = null;
- if (!isset($level_list[$slb->level])) {
- $level = ServeBonusLevel::find()->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED, 'level' => $slb->level])->one();
- if ($level) {
- $level_list[$slb->level] = $level;
- } else {
- $level_list[$slb->level] = null;
- }
- } else {
- $level = $level_list[$slb->level];
- }
- if (!$level) unset($servebonus_list[$lv]);
- //计算金额
- if ($level->is_to_bonus && $level->to_bonus_price > 0) {
- CapitalLog::$capitalType = 'commission';
- $total_settled = CapitalLog::find()->where(['user_id' => $slb->user_id, 'change_type' => 'add'])->sum('change_num') ?? 0;
- CapitalLog::$capitalType = 'commission_frozen';
- $total_nosettled = CapitalLog::find()->where(['user_id' => $slb->user_id, 'change_type' => 'add'])->sum('change_num') ?? 0;
- $total = bcadd($total_nosettled + $total_settled, 2);
- if ($total >= $level->to_bonus_price) {
- unset($servebonus_list[$lv]);
- $diff_num[$slb->level] += 1;
- }
- }
- }
- // 统计各个服务商等级的总人数
- $level_count = ServeBonus::find()
- ->select("count(id) num,level")
- ->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])
- ->groupBy("level")
- ->indexBy("level")
- ->orderBy("level asc")
- ->asArray()
- ->all();
- //减去相应的人头
- if ($level_count) {
- foreach ($level_count as &$lv_item) {
- if (isset($diff_num[$lv_item['level']])) {
- $lv_item['num'] = $lv_item['num'] - $diff_num[$lv_item['level']];
- if ($lv_item['num'] < 0) $lv_item['num'] = 0;
- }
- }
- }
- $temp_level_count = $level_count;
- $settlement_data = [];
- $total_commonisson = 0;// 出单奖励总奖励金额初始化
- // 循环订单详情,对不同商品进行对应的佣金结算
- foreach ($order_detail as $index => $detail) {
- $accumulation_num = $prev_commission = 0;// 叠加数量,叠加奖励;
- // 查询服务商商品
- $goods_setting = ServeBonusCommissionItemSetting::getOne([['mall_id' => $mallId,'item_id' => $detail['goods_id'], 'is_enable' => StatusEnum::ENABLED]], true, ['detail']);
- if (empty($goods_setting)) continue;
- //新增:云库存商品判断
- //if(empty($config['is_cloud_stock_open'])) continue;
- // $cloud_stock_goods = CloudStockGoods::findOne(['mall_id'=>$mallId,'goods_id'=>$detail['goods_id'],'status' => StatusEnum::ENABLED]);
- // $upgrade_bag_list = CloudStockUpgradeBag::findOne(['mall_id'=>$mallId,'goods_id'=>$detail['goods_id'],'status' => StatusEnum::ENABLED]);
- // if(empty($cloud_stock_goods) && empty($upgrade_bag_list)) continue;
- // 获取结算的金额
- if ($config['compute_type'] == 0) $order_money = $detail['goods_price'] / $order['total_num'] * $order['num'];// 支付金额
- if ($config['compute_type'] == 1) $order_money = $detail['goods_price'] - ($detail['cost_price'] * $detail['num']) + $detail['adjust_money'];// 商品利润
- if ($config['compute_type'] == 2) $order_money = $detail['price'] * $detail['num'];// 商品售价
- if ($order_money <= 0) continue;// 分红金额过小则没必要分红
- //添加订单记录
- $order_detail_id = !empty($detail['id']) ? $detail['id'] : 0;
- $order_log = ServeBonusOrderLog::findOne(['order_no'=>$from_order['order_no'],'order_detail_id'=>$order_detail_id]);
- if(empty($order_log)){
- $order_log_params = [
- 'mall_id'=> $mallId,
- 'order_id' => $from_order['id'],
- 'order_detail_id' => $order_detail_id,
- 'order_no' => $from_order['order_no'],
- 'order_type' => $order['order_type'],
- 'money' => $order_money,
- 'date' => $date,
- 'goods_id' => $detail['goods_id'],
- 'num' => $detail['num'],
- ];
- $res = ServeBonusOrderLog::setData($order_log_params);
- if ($res == false) throw new Exception(ServeBonusOrderLog::getStaticError());
- }
- $amounts = $amounts + $order_money;
- // 判断是否开启独立设置
- $is_gooods_alone = false;
- if (!empty($goods_setting['is_alone']) && $goods_setting['is_alone'] == 1) {
- // 商品独立分佣配置
- $level_calculate = $goods_setting['detail'];
- $is_gooods_alone = true;
- } else {
- // 等级分佣配置
- $level_calculate = $level_arr;
- }
- // 将等级设计倒叙,最高等级为排第一,计算各个等级开启叠加分红后的数量
- $level_count = $temp_level_count;
- $desc_level_calculate = ArrayHelper::arraySort($level_calculate, 'level', 'desc');
- foreach ($desc_level_calculate as $level) {
- $level_num = $level_count[$level['level']]['num'];// 该等级的人数
- $level_count[$level['level']]['num'] += $accumulation_num;// 统计的人数 = 等级人数 + 开启叠加分红等级人数
- // 判断是否开启叠加分红,开启叠加分红则增加对应的等级人数
- if ($level['is_accumulation'] == StatusEnum::ENABLED) {
- $accumulation_num += $level_num;
- }
- }
- // 对应的等级的出单奖励/加权分红计算
- foreach ($level_calculate as &$level) {
- $level_num = $level_count[$level['level']]['num'];// 统计的人数
- if ($level_num <= 0) {
- $extra_commonisson = 0;
- } else {
- if ($is_gooods_alone) {// 商品独立设置
- $level['is_percent_extra'] = $goods_setting['is_percent_extra'];
- $level['is_percent_prize'] = $goods_setting['is_percent_prize'];
- }
- if ($level['is_percent_extra'] == 0) {// 百分比
- $extra_commonisson = $level['extra_prize'] ? bcdiv($order_money * $level['extra_prize'] / $level_num, 100, 2) : 0;// 加权分红,单位:元
- $amounts = $order_money;
- } else {// 固定金额
- $extra_commonisson = $level['extra_prize'] ? bcdiv(($detail['num'] * $level['extra_prize']), $level_num, 2) : 0;// 加权分红,单位:元
- $amounts = ($detail['num'] * $level['extra_prize']);
- }
- // 出单奖励金额计算
- if ($level['level'] == $parent_level) {
- if ($level['is_percent_prize'] == 0) {// 百分比
- $total_commonisson += $level['prize'] ? bcdiv($order_money * $level['prize'], 100, 2) : 0;// 加权分红,单位:元
- } else {// 固定金额
- $total_commonisson += ($detail['num'] * $level['prize']);// 出单奖励,单位:元
- }
- }
- }
- $total_extra_commonisson = $level['is_accumulation'] == StatusEnum::ENABLED ? $extra_commonisson + $prev_commission : $extra_commonisson;
- // 单个商品的结算明细
- $settlement_data[$level['level']][] = [
- 'detail_id' => $detail['id'],
- 'goods_id' => $detail['goods_id'],
- 'goods_name' => $detail['goods_name'],
- 'amounts' => $amounts,
- 'prize' => 0,
- 'commonisson' => 0,
- 'is_accumulation' => $level['is_accumulation'],
- 'average_count' => $level_num,
- 'accumulation_prize' => $prev_commission,
- 'is_percent_extra' => $level['is_percent_extra'],
- 'extra_prize' => $level['extra_prize'],
- 'extra_commonisson' => $total_extra_commonisson,
- ];
- // 分红佣金计算
- $calculate[$level['level']] = [
- 'commission' => 0,
- 'extra_commission' => empty($calculate[$level['level']]['extra_commission']) ? $total_extra_commonisson : $calculate[$level['level']]['extra_commission'] + $total_extra_commonisson,
- 'settlement_data' => $settlement_data[$level['level']],
- ];
- $prev_commission += $extra_commonisson;// 低层级叠加的佣金
- }
- }
- // 结算的配置
- $settlement_config = [
- 'compute_type' => $config['compute_type'],// 佣金计算方式
- 'settlement_method' => $config['settlement_method'],// 结算方式
- ];
- // 分红计算
- foreach ($servebonus_list as $servebonus) {
- if (empty($calculate[$servebonus->level])) continue;
- // 判断用户是否符合额外分红条件
- if ($level[$servebonus->level]['extra_type'] == 1 && $servebonus->upgrade_status != 1) continue;
- if ($level[$servebonus->level]['extra_type'] == 2 && $servebonus->upgrade_status != 2) continue;
-
- $extra_settlement_config = $settlement_config;
- $extra_commission = $calculate[$servebonus->level]['extra_commission'];
- // 判断是否设置额外分红上限并且用户是否达到额外分红上限
- if ($level_arr[$servebonus->level]['extra_is_limit'] == 1) {
- // 已超额则直接退出
- if ($servebonus->temp_extra_commission > $level_arr[$servebonus->level]['extra_limit_price']) continue;
- // 没超额,但是加上奖励金额则超额,额外分红 = 限制金额 - 已有额外金额;
- if ($servebonus->temp_extra_commission + $calculate[$servebonus->level]['extra_commission'] > $level_arr[$servebonus->level]['extra_limit_price']) {
- $extra_commission = $level_arr[$servebonus->level]['extra_limit_price'] - $servebonus->temp_extra_commission;
- $extra_settlement_config['extra_msg'] = '额外分红金额已达到上限,应得额外分红:¥' . $calculate[$servebonus->level]['extra_commission'] . ',实得额外分红:¥' . $extra_commission;
- }
- }
- // 额外分红
- $rows[] = [
- 'mall_id' => $servebonus->mall_id,
- 'order_id' => $from_order['id'],
- 'order_no' => $from_order['order_no'],
- 'user_id' => $servebonus->user_id,
- 'type' => 2,
- 'level' => $servebonus->level,// 服务商等级
- 'amounts' => $calculate[$servebonus->level]['settlement_data'][0]['amounts'],
- 'commission' => $extra_commission,
- 'settlement_config' => Json::encode($extra_settlement_config),
- 'settlement_data' => Json::encode($calculate[$servebonus->level]['settlement_data']),
- 'date' => $date,
- 'created_at' => $time,
- 'updated_at' => $time,
- 'is_cloud_stock' => 1,
- ];
- // 增加额外分红的临时额度
- $servebonus->temp_extra_commission += $calculate[$servebonus->level]['extra_commission'];
- $servebonus->save();
- // 计算出单奖励金额
- if (!empty($user['parent_id']) && $user['parent_id'] == $servebonus->user_id) {
- $parent_level = $servebonus->level;
- $commonisson = $total_commonisson;// 出单奖励,单位:元
- }
- }
- // 保存数据
- if (!empty($rows)) {
- $trans = Yii::$app->db->beginTransaction();
- try {
- // 今日出单记录
- if (!empty($user['parent_id']) && !empty($commonisson)) {
- //该笔订单是否已出单
- $is_add = ServeBonusAchievement::findOne(['user_id' => $user['parent_id'], 'buy_uid' => $user_id,'order_id' => $from_order['id'], 'order_no' => $from_order['order_no']]);
- if(empty($is_add)){
- $achievement = ['mall_id' => $mallId, 'user_id' => $user['parent_id'], 'buy_uid' => $user_id, 'level' => $parent_level, 'order_id' => $from_order['id'], 'order_no' => $from_order['order_no'], 'prize' => $commonisson, 'date' => $date];
- $res = ServeBonusAchievement::setData($achievement);
- if ($res == false) throw new Exception(ServeBonusAchievement::getStaticError());
- }
- }
- // 生成数据
- $field = ['mall_id','order_id','order_no','user_id','type','level','amounts','commission','settlement_config','settlement_data','date','created_at','updated_at','is_cloud_stock'];
- $res = Yii::$app->db->createCommand()->batchInsert(ServeBonusRewardLog::tableName(), $field, $rows)->execute();
- if ($res == false) throw new Exception(ServeBonusRewardLog::getStaticError());
- $trans->commit();
- } catch (Exception $e) {
- $trans->rollBack();
- $this->setError($e->getMessage());
- return false;
- }
- }
- if(!empty($order['settle_log_id'])){
- $log = ServeBonusAchievementSettleLog::findOne($order['settle_log_id']);
- if($log){
- $log->not_yet_num = bcsub($log->not_yet_num,$order['num']);
- $log->save();
- }
- }
- $serveBonus = ServeBonus::findOne(['user_id'=>$user_id,'status'=>StatusEnum::ENABLED]);
- if(empty($serveBonus)) return true;
- if(in_array($order['changes_type'],[CloudStockEnum::CHANGE_TYPE_INCREASE_FILL,CloudStockEnum::CHANGE_TYPE_INCREASE_UPGRADE_BAG_GIVE])){
- // 获取结算周期,0=天,1=周,2=月
- $compute_period = $config['compute_period'];
- switch ($compute_period) {
- case 1:
- $start_day = date("Ymd", time());
- $end_day = $start_day;
- break;
- case 2:
- $start_day = date('Ymd', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600));
- $end_day = date('Ymd', (time() + (7 - (date('w') == 0 ? 7 : date('w'))) * 24 * 3600));
- break;
- case 3:
- $start_day = date("Ym01", time());
- $end_day = date('Ymd', strtotime(date('Y-m-01', time()). ' 1 month -1 day'));
- break;
- }
- //当前期数是否已有记录
- $period_log = ServeBonusCloudStockPeriod::findOne(['user_id'=>$user_id,'compute_period'=>$compute_period,'start_time' => $start_day,'end_time' => $end_day]);
- if(empty($period_log)){
- $period_log = new ServeBonusCloudStockPeriod();
- $period_log->user_id = $user_id;
- $period_log->mall_id = $mallId;
- $period_log->period_num = ServeBonusCloudStockPeriod::getPrevPeriodNum($mallId,$user_id);
- $period_log->compute_period = $compute_period;
- $period_log->start_time = $start_day;
- $period_log->end_time = $end_day;
- }
- //个人补货业绩
- $amounts = 0;
- if($order['changes_type'] == CloudStockEnum::CHANGE_TYPE_INCREASE_UPGRADE_BAG_GIVE){
- // $cloud_stock_goods = CloudStockGoods::findOne(['mall_id'=>$mallId,'goods_id'=>$order['goods_id'],'status' => StatusEnum::ENABLED]);
- // if(!empty($cloud_stock_goods)){
- // $agent = CloudStockAgent::findOne(['mall_id' => $mallId, 'user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
- // $agent_price_arr = json_decode($cloud_stock_goods['agent_price'],true);
- // $price_arr = array_column($agent_price_arr,'price','level');
- // $amounts = $price_arr[$agent->level]? $price_arr[$agent->level] * $order['num'] : 0;
- // }
- $amounts = $from_order['pay_money'];
- }else{
- $amounts = $from_order['pay_money'] / $order['total_num'] * $order['num'];
- }
- if(empty($amounts)) return true;
- //等级补货业绩 实时计算
- $amounts_num = 0;
- //等级分红金额 实时计算
- //$total_amounts_num = 0;
- //分红结算金额
- //$commission = 0;
- $period_log->amounts += $amounts;
- //$period_log->amounts_num = $amounts_num;
- //$period_log->total_amounts_num = $total_amounts_num;
- //$period_log->commission = $commission;
- if(!$period_log->save()) throw new Exception(ServeBonusCloudStockPeriod::getStaticError());
- }
- return true;
- }catch(\Exception $e){
- $exception = FormatHelper::exception($e, '云库存订单触发服务商分红计算错误');
- echo $exception;
- $this->setError($exception);
- return false;
- }
- }
- }
|