| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- <?php
- namespace addons\WriteOff\common\logic;
- use addons\WriteOff\common\models\WriteOffMember;
- use addons\WriteOff\common\models\WriteOffMemberLog;
- use addons\WriteOff\common\models\WriteOffSetting;
- use addons\WriteOff\common\models\WriteOffUser;
- use addons\WriteOff\common\models\WriteOffLevel;
- use addons\WriteOff\common\models\WriteOffPromoteOrderLog;
- use addons\WriteOff\common\models\WriteOffAwardLog;
- use addons\WriteOff\common\models\WriteOffCommissionJob;
- use addons\WriteOff\common\helpers\QrcodeHelper;
- use addons\WriteOff\common\enums\WriteOffEnum;
- use services\common\UserWalletService;
- use common\enums\AddonsEnum;
- use common\enums\RabbitMqEnum;
- use common\enums\StatusEnum;
- use common\helpers\TaskHelper;
- use common\models\mall\MallAddons;
- use common\models\order\Order;
- use common\models\order\OrderDetail;
- use common\traits\ErrorTrait;
- use PhpAmqpLib\Message\AMQPMessage;
- use common\helpers\LockHelper;
- use common\enums\RedisKeyEnum;
- use yii\helpers\Json;
- use yii\db\Exception;
- use Yii;
- class RewardLogic
- {
- use ErrorTrait;
- public static function reward($params){
- $order = Order::findOne($params['id']);
- $order_id = $order['id'];
- $mall_id = $order['mall_id'];
- $isInstall = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_WRITE_Off);
- if(!$isInstall) return true;
- // 获取配置
- $config = Yii::$app->services->setting->addons->get($mall_id, WriteOffEnum::ADDONS_NAME, 'basic');
- if(empty($config['is_enable'])) return true;
- $select = "id,mall_id,goods_id,user_id,goods_price,order_id,num";
- $order_details = OrderDetail::find()->select($select)->where(['order_id' => $order_id])->asArray()->all();
- if (empty($order_details)) throw new \Exception("订单id={$order_id}的订单详情数据为空");
- $goods_ids = array_column($order_details, 'goods_id'); // 商品ids
- // 获取设置了奖励的商品
- $list = WriteOffSetting::find()->where(['goods_id' => $goods_ids, 'is_enable_promote_reward' => StatusEnum::ENABLED, 'status' => StatusEnum::ENABLED])->indexBy('goods_id')->asArray()->all();
- if (empty($list)) return true;
- $extra_info = Json::decode($order['extra_info']);
- if(empty($extra_info['write_off']['user_id'])) return true;;
- $user_id = $extra_info['write_off']['user_id'];
- $insert_wallet = [];
- $t = \Yii::$app->db->beginTransaction();
- try{
- if(!empty($config['is_enable_promote_reward'])){
- $insert_wallet = self::promoteReward($order,$user_id,$config,$list,$order_details);
- }
- if(!empty($insert_wallet)){
- $res = UserWalletService::batchHandleByQueue($insert_wallet);
- if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
- foreach ($insert_wallet as $k => $user) {
- $promote_commission_arr = [];
- $writeOffUser = WriteOffUser::find()->where(['mall_id'=>$mall_id,'user_id'=> $user['user_id'],'status' => StatusEnum::ENABLED])->one();
- if(empty($writeOffUser)) continue;
- if($user['capital_type'] == WriteOffEnum::PROMOTE_PRIZE){
- $writeOffUser->promote_commission += $user['money'];
- $promote_commission_arr = [
- 'mall_id' => $mall_id,
- 'user_id' => $user['user_id'],
- 'order_id' => $order['id'],
- 'order_no' => $order['order_no'],
- 'order_detail_id' => $user['source_table_id'],
- 'pay_money' => $order['pay_money'],
- 'buy_user_id' => $order['user_id'],
- ];
- }
- if($user['capital_type'] == WriteOffEnum::MANAGE_PRIZE){
- $writeOffUser->manage_commission += $user['money'];
- }
- $writeOffUser->total_commission += $user['money'];
- $res = $writeOffUser->save();
- if (empty($res)) throw new \Exception(WriteOffUser::getStaticError());
- if(!empty($promote_commission_arr)){
- $res = WriteOffPromoteOrderLog::setData($promote_commission_arr);
- if (empty($res)) throw new \Exception(WriteOffPromoteOrderLog::getStaticError());
- }
- }
- }
- $t->commit();
- return true;
- }catch(\Exception $e){
- $t->rollBack();
- \Yii::error('触发核销员奖励'.$e->getMessage());
- return false;
- }
- }
- public static function promoteReward($order,$user_id,$config,$list,$order_details){
- $mall_id = $order['mall_id'];
- $money = $order['pay_money'];
- $writeOffUser = WriteOffUser::find()->where(['mall_id'=>$mall_id,'user_id'=> $user_id,'status' => StatusEnum::ENABLED])->one();
- if(empty($writeOffUser)) throw new \Exception('核销员不存在');
- $level = WriteOffLevel::findOne(['mall_id'=>$mall_id,'level'=>$writeOffUser['level'],'status' => StatusEnum::ENABLED]);
- if(empty($level) || empty($level['is_enable_promote_reward'])) throw new \Exception('该等级未开启促销奖励');
- //$reward_money = $money * $level['promote_reward_prize'] / 100;
- foreach ($order_details as $detail) {
- $goods_id = $detail['goods_id'];
- $setting = $list[$goods_id] ?? [];
- if (empty($setting)) continue;
- // $settlement_method = $setting['settlement_method'];
- // if ($settlement_method != $order_status) continue;
- $pay_money = $detail['goods_price'] + $detail['adjust_money'];
- $reward_money = bcmul($level['promote_reward_prize'] / 100, $pay_money);
- if ($reward_money <= 0) continue;
- $insert_wallet[] = [
- 'mall_id' => $mall_id,
- 'user_id' => $user_id,
- 'is_frozen' => false,
- 'wallet_type' => 'commission',
- 'money' => $reward_money,
- 'desc' => '获得订单('.$order['id'].')促销奖励',
- 'source_table' => OrderDetail::tableName(),
- 'source_table_id' => $detail['id'],
- 'from_type' => WriteOffEnum::ADDONS_NAME,
- 'capital_type' => WriteOffEnum::PROMOTE_PRIZE,
- 'order_no' =>$order['order_no'],
- 'contributor_id' =>$order['user_id'],
- ];
- //管理奖励
- if (!empty($config['is_enable_store_manage_reward']) && $config['manage_reward_rate'] > 0) {
- $store_id = $writeOffUser['store_id'];
- $writeOffUserList = WriteOffUser::find()->where(['mall_id'=>$mall_id,'status'=>StatusEnum::ENABLED,'store_id'=>$store_id,'is_enable_manage_reward'=>1])->asArray()->all();
- if(!empty($writeOffUserList)){
- $manage_reward = $pay_money * $config['manage_reward_rate'] / 100;
- if($manage_reward > 0){
- foreach($writeOffUserList as $item){
- $insert_wallet[] = [
- 'mall_id' => $mall_id,
- 'user_id' => $item['user_id'],
- 'is_frozen' => false,
- 'wallet_type' => 'commission',
- 'money' => $manage_reward,
- 'desc' => '获得订单('.$order['id'].')管理奖励',
- 'source_table' => OrderDetail::tableName(),
- 'source_table_id' => $detail['id'],
- 'from_type' => WriteOffEnum::ADDONS_NAME,
- 'capital_type' => WriteOffEnum::MANAGE_PRIZE,
- 'order_no' =>$order['order_no'],
- 'contributor_id' =>$order['user_id'],
- ];
- }
- }
- }
- }
-
- }
- return $insert_wallet;
- }
- public static function writeOffReward($params){
- try{
- $writeOffMemberLog = WriteOffMemberLog::findOne($params['id']);
- if(empty($writeOffMemberLog)) throw new \Exception('数据不存在');
- $writeOffUser = WriteOffUser::findOne(['id' => $writeOffMemberLog['source_table_id'],'status' => StatusEnum::ENABLED]);
- if(empty($writeOffUser)) throw new \Exception('核销员状态异常');
- $mall_id = $writeOffUser['mall_id'];
- $level = WriteOffLevel::findOne(['mall_id'=>$mall_id,'level'=>$writeOffUser['level'],'status' => StatusEnum::ENABLED]);
- if(empty($level) || empty($level['is_enable_write_off_reward'])) throw new \Exception('该等级未开启核销奖励');
- $write_off_reward_proportion = json_decode($level['write_off_reward_proportion'],true);
- if(empty($write_off_reward_proportion)) throw new \Exception('阶梯奖励设置异常');
- $write_off_reward_proportion = array_reverse($write_off_reward_proportion);
- $counts = count($write_off_reward_proportion);
- $money = 0;
- $today_start = strtotime(date('Y-m-d 00:00:00',time()));
- $today_end = strtotime(date('Y-m-d 23:59:59',time()));
- $log_today = WriteOffMemberLog::find()
- ->where(['source_table' => WriteOffUser::tableName(),'source_table_id' => $writeOffUser['id'],'change_type' => 'sub'])
- ->andWhere(['>=','created_at',$today_start])
- ->andWhere(['<=','created_at',$today_end])
- ->sum('change_num') ?? 0;
- if($log_today > $counts){
- $proportion_first = $write_off_reward_proportion[0];
- $money = $proportion_first['money'];
- }else{
- foreach($write_off_reward_proportion as $key => $proportion){
- if($log_today == $counts - $key){
- $money = $proportion['money'];
- break;
- }
- }
- }
- if($money > 0){
- $insert_wallet[] = [
- 'mall_id' => $mall_id,
- 'user_id' => $writeOffUser['user_id'],
- 'is_frozen' => false,
- 'wallet_type' => 'commission',
- 'money' => $money,
- 'desc' => '核销用户('.$writeOffMemberLog['user_id'].')获得核销奖励',
- 'source_table' => WriteOffMemberLog::tableName(),
- 'source_table_id' => $writeOffMemberLog['id'],
- 'from_type' => WriteOffEnum::ADDONS_NAME,
- 'capital_type' => WriteOffEnum::WRITE_OFF_PRIZE,
- 'order_no' =>$writeOffMemberLog['order_no'],
- 'contributor_id' =>$writeOffMemberLog['user_id'],
- ];
- $res = UserWalletService::batchHandleByQueue($insert_wallet);
- if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
- $writeOffUser->commission += $money;
- $writeOffUser->total_commission += $money;
- if(!$writeOffUser->save()) throw new \Exception(WriteOffUser::getStaticError());
- }
- return true;
- }catch(\Exception $e){
- \Yii::error('核销奖励发放异常,params:'.json_encode($params).',error:'.$e->getMessage());
- return false;
- }
- }
- public static function achievementPromoteReward($mall_id){
- $isInstall = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_WRITE_Off);
- if(!$isInstall) return true;
- // 获取配置
- $config = Yii::$app->services->setting->addons->get($mall_id, WriteOffEnum::ADDONS_NAME, 'basic');
- if(empty($config['is_enable']) || empty($config['is_enable_promote_reward'])) return true;
- $continue = false;
- $compute_period = $config['compute_period'];
- switch ($config['compute_period']) {
- case 0:
- 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;
- }
- if ($continue) return true;
- $date_limit = $start_day . '-' . $end_day;
- $job = WriteOffCommissionJob::findOne(['mall_id' => $mall_id, 'compute_period' => $compute_period, 'date_limit' => $date_limit, 'status' => StatusEnum::ENABLED]);
- if ($job) return true;
- // 生成执行记录
- $job = new WriteOffCommissionJob();
- $job->mall_id = $mall_id;
- $job->date_limit = $date_limit;
- $job->compute_period = $compute_period;
- if (!$job->save()) throw new Exception($job->getErrorMessage());
- try {
- self::addCommissionLog($mall_id,$start_day, $end_day);
- return true;
- } catch (Exception $e) {
- \Yii::error('促销业绩奖励结算异常:'.$e->getMessage());
- return false;
- }
- }
- public static function addCommissionLog($mall_id,$start_day, $end_day){
- $start_day = strtotime($start_day);
- $end_day = strtotime(date('Y-m-d 23:59:59',strtotime($end_day)));
- $level_list = WriteOffLevel::find()
- ->where(['mall_id'=>$mall_id,'status' => StatusEnum::ENABLED,'is_enable_promote_reward_achievement'=>1])
- ->indexBy('level')
- ->asArray()
- ->all();
- if(empty($level_list)) return true;
- $levels = array_column($level_list,'level');
- foreach($level_list as &$level){
- $level['promote_achievement_reward_proportion'] = json_decode($level['promote_achievement_reward_proportion'],true);
- if(empty($level['promote_achievement_reward_proportion'])){
- unset($level);
- }
- $level['promote_achievement_reward_proportion'] = array_reverse($level['promote_achievement_reward_proportion']);
- }
- $write_off_user_list = WriteOffUser::find()
- ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])
- ->andWhere(['in','level',$levels])
- ->select('id,user_id,level')
- ->asArray()
- ->all();
- if (empty($write_off_user_list)) return true;
- $total = WriteOffPromoteOrderLog::find()
- ->where(['mall_id'=>$mall_id,'status'=>StatusEnum::ENABLED])
- ->andWhere(['>=','created_at',$start_day])
- ->andWhere(['<=','created_at',$end_day])
- ->indexBy('user_id')
- ->groupBy('user_id')
- ->select('sum(pay_money) as money,user_id')
- ->asArray()
- ->all();
- if(empty($total)) return true;
- $insert_wallet = [];
- $trans = \Yii::$app->db->beginTransaction();
- try{
- foreach($write_off_user_list as $write_off_user){
- $achievement = 0;
- $rate = 0;
- if(empty($level_list[$write_off_user['level']])) continue;
- $proportion_list = $level_list[$write_off_user['level']]['promote_achievement_reward_proportion'];
- if(!empty($total[$write_off_user['user_id']]['money'])){
- $achievement = $total[$write_off_user['user_id']]['money'];
- }
- foreach($proportion_list as $proportion){
- if($achievement >= $proportion['money_start'] && $achievement <= $proportion['money_end']){
- $rate = $proportion['proportion'];
- }
- }
- $reward_money = $achievement * $rate / 100;
- if($reward_money > 0){
- $params = [
- 'mall_id' => $mall_id,
- 'user_id' => $write_off_user['user_id'],
- 'achievement_sum' => $achievement,
- 'award_money' => $reward_money,
- 'rate' => $rate,
- 'is_settlement' => 1,
- ];
- $res = WriteOffAwardLog::setData($params);
- if (empty($res)) throw new \Exception(WriteOffAwardLog::getStaticError());
- $writeOffUser = WriteOffUser::findOne($write_off_user['id']);
- $writeOffUser->promote_achievement_commission += $reward_money;
- $writeOffUser->total_commission += $reward_money;
- if(!$writeOffUser->save()) throw new \Exception(WriteOffUser::getStaticError());
- $insert_wallet[] = [
- 'mall_id' => $mall_id,
- 'user_id' => $write_off_user['user_id'],
- 'is_frozen' => false,
- 'wallet_type' => 'commission',
- 'money' => $reward_money,
- 'desc' => '促销阶梯奖励',
- 'source_table' => WriteOffAwardLog::tableName(),
- 'source_table_id' => $res->id,
- 'from_type' => WriteOffEnum::ADDONS_NAME,
- 'capital_type' => WriteOffEnum::ACHIEVEMENT_PROMOTE_PRIZE,
- ];
- }
- }
- if(!empty($insert_wallet)){
- $res = UserWalletService::batchHandleByQueue($insert_wallet);
- if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
- }
- $trans->commit();
- return true;
- }catch(\Exception $e){
- $trans->rollBack();
- throw new \Exception($e->getMessage());
- }
-
- }
- }
|