| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- <?php
- namespace addons\ServeBonus\common\logic;
- use addons\ServeBonus\common\enums\ServeBonusEnum;
- use addons\ServeBonus\common\models\ServeBonusRewardLog;
- use addons\ServeBonus\common\models\ServeBonus;
- use addons\ServeBonus\common\models\ServeBonusAchievement;
- use addons\ServeBonus\common\models\ServeBonusCommissionJob;
- use addons\ServeBonus\common\models\ServeBonusCommissionLog;
- use addons\ServeBonus\common\models\ServeBonusPeriod;
- use addons\ServeBonus\common\models\ServeBonusCloudStockPeriod;
- use addons\ServeBonus\common\models\ServeBonusOrderLog;
- use common\enums\AddonsEnum;
- use common\enums\StatusEnum;
- use common\enums\UserWalletEnum;
- use common\helpers\FormatHelper;
- use common\models\mall\Mall;
- use common\models\mall\MallAddons;
- use common\traits\ErrorTrait;
- use Exception;
- use services\common\UserWalletService;
- use Yii;
- use yii\helpers\Json;
- class CommissionLogLogic{
- use ErrorTrait;
- /**
- * 执行分红操作
- * @Author: ltm
- * @DateTime: 2021/11/5 0005 14:27
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @return bool
- */
- public function execute($mallId = 0, $isManual = false)
- {
- $where = [];
- !empty($mallId) && $isManual && $where['where'] = ['=', 'id' ,$mallId];// 手动执行单个商城分红操作
- $mall_list = Mall::getEnableMallList(true, $where);
- if(!empty($mall_list)){
- foreach ($mall_list as $mall){
- $mallId = $mall['id'];
- // 判断是否有安装该插件
- if (MallAddons::isInstall($mallId, AddonsEnum::ADDONS_NAME_SERVEBONUS) == false) continue;
- // 出单奖励记录
- $trans = Yii::$app->db->beginTransaction();
- try {
- $res = $this->calculate($mallId, $isManual);
- if($res === false) throw new Exception($this->getError());
- $trans->commit();
- } catch (Exception $e) {
- $trans->rollBack();
- }
- // 获取基础配置
- $config = Yii::$app->services->setting->addons->get($mallId, 'ServeBonus', 'basic');
- if ($config['is_enable'] == StatusEnum::ENABLED) {
- $continue = false;
- // 获取结算周期,0=天,1=周,2=月
- $compute_period = $config['compute_period'];
- if ($isManual == false) {
- switch ($compute_period) {
- case 1:
- $start_day = date("Ymd", strtotime("-1 day"));
- $end_day = $start_day;
- break;
- case 2:
- if (date('w') != 1) $continue = true;// 非周一直接退出
- $start_day = date("Ymd", strtotime("last Monday"));
- $end_day = date('Ymd', strtotime('-1 sunday', time()));;
- break;
- case 3:
- if (date('d') != 1) $continue = true;// 非当月1号直接退出
- $start_day = date("Ym01", strtotime("-1 month"));
- $end_day = date('Ymd', strtotime(date('Y-m', time()) . '-01 00:00:00') - 86400);
- break;
- }
- } else {
- $start_day = $end_day = date("Ymd", time());// 手动执行当日的订单分红
- }
- if ($continue) continue;
- $date_limit = $start_day . '-' . $end_day;
- $job = ServeBonusCommissionJob::findOne(['mall_id' => $mallId, 'compute_period' => $compute_period, 'date_limit' => $date_limit, 'status' => StatusEnum::ENABLED]);
- if ($job && $isManual == false) continue;
- // 生成执行记录
- if (empty($job)) {
- $job = new ServeBonusCommissionJob();
- $job->mall_id = $mallId;
- $job->date_limit = $date_limit;
- $job->compute_period = $compute_period;
- if (!$job->save()) throw new Exception($job->getErrorMessage());
- }
- $trans = Yii::$app->db->beginTransaction();
- try {
- $res = $this->addCommissionLog($mallId, $config, $start_day, $end_day);
- if($res === false) throw new Exception($this->getError());
- $trans->commit();
- } catch (Exception $e) {
- $trans->rollBack();
- }
- }
- }
- return true;
- }
- }
- //修复用
- public function fix($mallId = 0,$date=''){
- $where = [];
- $where['where'] = ['=', 'id' ,$mallId];// 手动执行单个商城分红操作
- $mall_list = Mall::getEnableMallList(true, $where);
- if(!empty($mall_list)){
- foreach ($mall_list as $mall){
- $mallId = $mall['id'];
- // 判断是否有安装该插件
- if (MallAddons::isInstall($mallId, AddonsEnum::ADDONS_NAME_SERVEBONUS) == false) continue;
- // 获取基础配置
- $config = Yii::$app->services->setting->addons->get($mallId, 'ServeBonus', 'basic');
- if ($config['is_enable'] == StatusEnum::ENABLED) {
- $compute_period = $config['compute_period'];
- if(empty($date))$date = date("Ymd", time());
- $start_day = $end_day = $date;// 手动执行当日的订单分红
- $date_limit = $start_day . '-' . $end_day;
- // 生成执行记录
- $job = new ServeBonusCommissionJob();
- $job->mall_id = $mallId;
- $job->date_limit = $date_limit;
- $job->compute_period = $compute_period;
- if (!$job->save()) throw new Exception($job->getErrorMessage());
- $trans = Yii::$app->db->beginTransaction();
- try {
- $res = $this->addCommissionLog($mallId, $config, $start_day, $end_day);
- if($res === false) throw new Exception($this->getError());
- $trans->commit();
- } catch (Exception $e) {
- $trans->rollBack();
- }
- }
- }
- return true;
- }
- }
- /**
- * 计算出单奖励
- * @Author: lun
- * @DateTime: 2022/1/25 0025 18:55
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $mallId
- * @param $isManual
- */
- private function calculate($mallId, $isManual)
- {
- try {
- $time = time();
- $yesterday = date("Ymd", $time);
- $yesterday = $isManual ? $yesterday : date("Ymd", strtotime("-1 day"));
- // 获取出单奖励列表
- $list = ServeBonusAchievement::getServeBonusAchievement([['mall_id' => $mallId, 'date' => $yesterday, 'is_settlement' => StatusEnum::DISABLED, 'status' => StatusEnum::ENABLED]]);
- if (empty($list)) return true;
- // 将同级别的用户组合为数组
- foreach ($list as $item) {
- $bonus_uids[$item['level']][] = $item['user_id'];
- }
- // 循环操作
- foreach ($list as $item) {
- $num = count(array_unique($bonus_uids[$item['level']]));// 该等级的人数
- $commission = sprintf("%.2f",substr(sprintf("%.3f", $item['prize'] / $num), 0, -1));// 佣金
- $new_uids = array_unique($bonus_uids[$item['level']]);// 移除重复的元素
- foreach ($new_uids as $uid) {
- $rows[] = [
- 'mall_id' => $mallId,
- 'order_id' => $item['order_id'],
- 'order_no' => $item['order_no'],
- 'user_id' => $uid,
- 'type' => 1,
- 'level' => $item['level'],// 服务商等级
- 'amounts' => $item['prize'],
- 'commission' => $commission,
- 'settlement_data' => Json::encode([
- 'amounts' => $item['prize'],
- 'commonisson' => $commission,
- 'average_count' => $num,
- ]),
- 'date' => $yesterday,
- 'created_at' => $time,
- 'updated_at' => $time,
- ];
- }
- // 修改统计人数,将此条数据改为已结算
- ServeBonusAchievement::updateAll(['average_count' => $num, 'is_settlement' => StatusEnum::ENABLED], ['id' => $item['id']]);
- }
- // 生成数据
- if (!empty($rows)) {
- $field = ['mall_id','order_id','order_no','user_id','type','level','amounts','commission','settlement_data','date','created_at','updated_at'];
- $res = Yii::$app->db->createCommand()->batchInsert(ServeBonusRewardLog::tableName(), $field, $rows)->execute();
- if ($res == false) throw new \yii\db\Exception(ServeBonusRewardLog::getStaticError());
- }
- return true;
- } catch (Exception $e) {
- return false;
- }
- }
- /**
- * 增加ServeBonus分红佣金
- * @Author: ltm
- * @DateTime: 2021/11/5 0005 14:27
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $mallId
- * @param $config
- * @param $start_day
- * @param $end_time
- * @return bool
- */
- private function addCommissionLog($mallId, $config, $start_day, $end_day)
- {
- if ($config['is_enable'] == StatusEnum::DISABLED) {
- Yii::error('系统没有开启服务商提成');
- return true;
- }
- try {
- // 初始化数据
- $time = time();
- $table_name = ServeBonusCommissionLog::tableName();
- // 获取所有服务商列表
- $servebonus_list = ServeBonus::find()->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])->asArray()->all();
- if (empty($servebonus_list)) return true;
- $servebonus_arr = array_column($servebonus_list,'user_id');
- // 获取分红奖励列表
- $reward_list = ServeBonusRewardLog::find()
- ->select('user_id,sum(amounts) amounts,sum(commission) commission,type')
- ->where(['mall_id' => $mallId, 'is_settlement' => StatusEnum::DISABLED])
- ->andFilterWhere(['between', 'date', $start_day, $end_day])
- ->groupBy('user_id,type')
- ->orderBy("user_id desc,type asc")
- ->asArray()
- ->all();
- //获取业绩分红奖励列表
- $achievement_reward_list = ServeBonusCloudStockPeriod::find()
- ->select('max(id) as id,user_id,amounts,amounts_num,total_amounts_num,commission,start_time,end_time')
- ->where(['mall_id' => $mallId, 'is_settlement' => StatusEnum::DISABLED])
- ->andWhere(['=', 'start_time', $start_day])
- ->andWhere(['=', 'end_time', $end_day])
- ->groupBy('user_id')
- ->orderBy("id desc")
- ->asArray()
- ->all();
- $level_arr = array_unique(array_column($servebonus_list,'level'));
- $servebonus_list = array_column($servebonus_list,null,'user_id');
- $total = [];
- foreach($level_arr as $level){
- $total[$level]['amounts_num'] = ServeBonusCloudStockPeriod::getAmountsNum($mallId,$level,$start_day,$end_day);
- $total[$level]['total_amounts_num'] = ServeBonusOrderLog::getTotalAmountsNum($mallId,$level,$start_day,$end_day);
- }
- if(!empty($achievement_reward_list)){
- foreach($achievement_reward_list as &$achievement_reward){
- $achievement_reward['type'] = ServeBonusEnum::BOUNS_TYPE_ACHIEVEMENT;
- if(empty($total[$servebonus_list[$achievement_reward['user_id']]['level']])) continue;
- $achievement_reward['amounts_num'] = $total[$servebonus_list[$achievement_reward['user_id']]['level']]['amounts_num'];
- $achievement_reward['total_amounts_num'] = $total[$servebonus_list[$achievement_reward['user_id']]['level']]['total_amounts_num'];
- $achievement_reward['commission'] = $achievement_reward['amounts'] / $achievement_reward['amounts_num'] * $achievement_reward['total_amounts_num'];
- }
- }
- $reward_list = array_merge($reward_list,$achievement_reward_list);
- if (empty($reward_list)) return true;
- // 获取本期期数id
- $period_id = ServeBonusPeriod::setData($mallId);
- $servebonus_commission = $forever_uids = [];// 用户佣金、记录加权分红、出单奖励用户初始化
- $total_commission = $total_extra_commission = $total_achievement_commission = 0;// 统计加权分红跟出单奖励总额
- $total_settlement_uids = [];
- // 生成计算好的结算数据
- foreach ($reward_list as $item) {
- if (in_array($item['user_id'], $servebonus_arr)) {
- // 加权分红跟出单奖励数据处理
- if(!$servebonus_commission[$item['user_id']]['commission']){
- $servebonus_commission[$item['user_id']]['commission'] = 0;
- }
- if(!$servebonus_commission[$item['user_id']]['extra_commission']){
- $servebonus_commission[$item['user_id']]['extra_commission'] = 0;
- }
- if(!$servebonus_commission[$item['user_id']]['achievement_commission']){
- $servebonus_commission[$item['user_id']]['achievement_commission'] = 0;
- }
- if ($item['type'] == ServeBonusEnum::BOUNS_TYPE_FOREVER) {
- $forever_uids[] = $item['user_id'];// 出单奖励用户id
- $servebonus_commission[$item['user_id']]['commission'] = $item['commission'];
- $total_commission += $item['commission'];
- } elseif($item['type'] == ServeBonusEnum::BOUNS_TYPE_ACHIEVEMENT){
- $servebonus_commission[$item['user_id']]['achievement_commission'] = $item['commission'];
- $total_achievement_commission += $item['commission'];
- $log = ServeBonusCloudStockPeriod::findOne($item['id']);
- $log->is_settlement = StatusEnum::ENABLED;
- $log->period_id = $period_id;
- $log->updated_at = $time;
- $log->amounts_num = $item['amounts_num'];
- $log->total_amounts_num = $item['total_amounts_num'];
- $log->commission = $item['commission'];
- if(!$log->save()) throw new \Exception(ServeBonusCloudStockPeriod::getStaticError());
- }else {
- $servebonus_commission[$item['user_id']]['commission'] = $servebonus_commission[$item['user_id']]['commission'] ?? 0;
- $servebonus_commission[$item['user_id']]['extra_commission'] = $item['commission'];
- $total_extra_commission += $item['commission'];
- }
- $rows[$item['user_id']] = [
- 'mall_id' => $mallId,
- 'user_id' => $item['user_id'],
- 'period_id' => $period_id,
- 'commission' => empty($rows[$item['user_id']]['commission']) ? $servebonus_commission[$item['user_id']]['commission'] : $rows[$item['user_id']]['commission'],
- 'extra_commission' => empty($rows[$item['user_id']]['extra_commission']) ? $servebonus_commission[$item['user_id']]['extra_commission'] : $rows[$item['user_id']]['extra_commission'],
- 'compute_period' => $config['compute_period'],
- 'start_time' => $start_day,
- 'end_time' => $end_day,
- 'created_at' => $time,
- 'updated_at' => $time,
- 'achievement_commission' => empty($rows[$item['user_id']]['achievement_commission']) ? $servebonus_commission[$item['user_id']]['achievement_commission'] : $rows[$item['user_id']]['achievement_commission'],
- ];
- $total_settlement_uids[] = $item['user_id'];
- }
- }
- if (empty($rows)) return true;
- // 生成数据
- $field = ['mall_id','user_id','period_id','commission','extra_commission','compute_period','start_time','end_time','created_at','updated_at','achievement_commission'];
- Yii::$app->db->createCommand()->batchInsert($table_name, $field, $rows)->execute();
- // 数据生成完成记录表修改结算状态
- ServeBonusRewardLog::updateAll(
- [
- 'is_settlement' => StatusEnum::ENABLED,
- 'period_id' => $period_id,
- 'updated_at' => $time
- ],
- ['and', ['mall_id' => $mallId, 'is_settlement' => StatusEnum::DISABLED],['between', 'date', $start_day, $end_day]]
- );
- // 增加对应服务商分佣金额
- $log_list = ServeBonusCommissionLog::getServeBonusCommissionLog([['mall_id' => $mallId,'period_id' => $period_id,'start_time' => $start_day,'end_time' => $end_day]]);
- foreach ($log_list as $item) {
- $wallet_money = $item['commission'] + $item['extra_commission'] + $item['achievement_commission'];
- if (empty($wallet_money)) continue;
- $insert_wallet[] = [
- 'mall_id' => $mallId,
- 'user_id' => $item['user_id'],
- 'is_frozen' => false,
- 'wallet_type' => 'commission',
- 'money' => $wallet_money,
- 'desc' => '服务商分红佣金',
- 'source_table' => $table_name,
- 'source_table_id' => $item['id'],
- 'from_type' => ServeBonusEnum::ADDONS_NAME,
- 'capital_type' => UserWalletEnum::BOUNS,
- ];
- }
- if (!empty($insert_wallet)) {
- $res = UserWalletService::batchHandleByQueue($insert_wallet);
- if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
- }
- // 增加用户服务商金额
- $commission_logs = ServeBonusCommissionLog::find()->where(['period_id' => $period_id, 'status' => StatusEnum::ENABLED])->asArray()->all();
- foreach ($commission_logs as $commission_log) {
- $ServeBonus = ServeBonus::findOne(['mall_id' => $mallId, 'user_id' => $commission_log['user_id'], 'status' => StatusEnum::ENABLED]);
- if (empty($ServeBonus)) continue;
- if (!empty($commission_log['commission'])) {// 出单奖励
- $ServeBonus->commission += $commission_log['commission'];// 增加出单奖励
- $ServeBonus->total_commission += $commission_log['commission'];// 增加总累计
- }
- if (!empty($commission_log['extra_commission'])) {// 加权分红
- $ServeBonus->extra_commission += $commission_log['extra_commission'];// 增加加权分红奖励
- $ServeBonus->total_commission += $commission_log['extra_commission'];// 增加总累计
- }
- if (!empty($commission_log['achievement_commission'])) {// 加权分红
- $ServeBonus->achievement_commission += $commission_log['achievement_commission'];// 增加加权分红奖励
- $ServeBonus->total_commission += $commission_log['achievement_commission'];// 增加总累计
- }
- $ServeBonus->temp_extra_commission = $ServeBonus->extra_commission;// 重置加权平分计算金额
- $ServeBonus->period_num = $ServeBonus->period_num + 1;// 增加结算期数
- if (!$ServeBonus->save()) throw new \Exception($ServeBonus->getErrorMessage());
- }
- // 修改商城本期分红数据
- ServeBonusPeriod::setData($mallId,[
- 'id' => $period_id,
- 'amounts' => $total_commission,
- 'amounts_num' => count(array_unique($forever_uids)),
- 'extra_amounts' => $total_extra_commission,
- 'total_amounts_num' => count(array_unique($total_settlement_uids)),
- 'compute_period' => $config['compute_period'],
- 'start_time' => $start_day,
- 'end_time' => $end_day,
- 'achievement_commission' => $total_achievement_commission,
- ]);
- return true;
- } catch (Exception $e) {
- $exception = FormatHelper::exception($e, "mall_id={$mallId} 服务商定时分红任务失败");
- echo $exception;
- Yii::error($exception);
- $this->setError($exception);
- return false;
- }
- }
- }
|