isInit) return; //避免重复生成配置 ini_set('serialize_precision',14); $month = $count_date; if(empty($month)) die("参数错误"); $this->adddata = [];//置空否者会脚本进来会重复计算 $this->date = $month; $tarry = explode('-',$month); $this->year= $tarry[0]; if(strlen($tarry[1]) < 2) $tarry[1]="0".$tarry[1]; $this->month= $tarry[1]; $this->beginThismonth=mktime(0,0,0,$tarry[1],1,$tarry[0]); $this->endThismonth=mktime(0,0,0,$tarry[1]-0+1,1,$tarry[0])-1; $this->settleupMarketorderModel=SM("settleup_marketorder","tab_"); $this->marketAltogetherModel=SM("market_altogether","tab_"); $this->isInit = true; } /** * 更新某月毛利数据 */ public function setFreeMonth($count_date) { $this->configInit($count_date); $this->setSettleupMarketorder(); } /** * 计算公司毛利 */ private function setSettleupMarketorder() { $this->setIsTipData(); $this->getInsideCompanyid(); $this->getChannelRatio(); $this->getTaxRatio(); $this->getAllDownFlowSpend(); $this->getAllGameInfo(); $this->getCompanyOtherInfo(); $this->getMarketUserInfo(); $this->getPuStatement(); $this->getPuSpecialStatement(); $this->performanceSet(); $this->settleupMarketorderDbSave(); echo "{$this->year}-{$this->month}生成成功".PHP_EOL; } /** * 获取是否标红提示数据,旧数据比对 */ private function setIsTipData() { $dbres = $this->settleupMarketorderModel->where(['pay_time'=>$this->date])->select(); if($dbres){ foreach ($dbres as $key => $v) { $this->oldMarketPerformance[$v['company_id']][$v['game_name']]['company_profit'] = $v['company_profit']; } }else{ $this->oldMarketPerformance = false; } //取消所有提示 $this->settleupMarketorderModel->where("1=1")->save(["is_tip"=>0]); } /** * 获取公司内部公司id */ private function getInsideCompanyid() { $res = M("PromoteCompany","tab_")->where("is_inside = 1")->field("id")->select(); if($res){ $res = array_column($res,"id"); $res[] = 0; }else{ $res = [0]; } $this->inSideCompanyIds = implode(",",$res); } /** * 支付服务商渠道费 * TODO:当前默认除了绑定币其他渠道都1% */ private function getChannelRatio() { $res = M("payment_merchant","tab_")->getField("id,config",true); foreach ($res as $k => $v) { $res[$k] = 1; //------begin------注释的部分表示按实际配置收取 // $config = json_decode($v,true); // if(array_key_exists("channel_rate",$config) && $config['channel_rate'] > 0){ // $res[$k] = $config['channel_rate']; // }else{ // $res[$k] = 0; // } //----------end------ } $res[0] = 1;//平台币 $res[-1] = 0;//绑定币 $this->channelRatio = $res; unset($res); } /** * 获取公司税率 */ private function getTaxRatio() { $where = [ "time"=>['ELT',$this->beginThismonth] ]; $tax_data = M("tax_radio","tab_") ->field("tax_radio") ->order("time desc") ->where($where) ->find(); if($tax_data){ $this->taxRatio = $tax_data['tax_radio']; }else{ $this->taxRatio = 0; } } /** * 获取所有下游公司支付信息 */ private function getAllDownFlowSpend() { $where = [ "pay_status"=>1, "s.is_check"=>1, "payed_time"=>["between",[$this->beginThismonth,$this->endThismonth]], "p.company_id"=>["NOT IN",$this->inSideCompanyIds], "p.company_belong"=>['GT',0] ]; //测试 // $where['p.company_id'] = 43; $dbres = M("Spend","tab_") ->alias("s") ->field("substring_index(game_name, '(', 1) relation_game_name, SUM(pay_amount) pay_amount, IFNULL(SUM(CASE WHEN is_refund = 1 THEN pay_amount ELSE 0 END),0) as refund_amount, p.company_id,p.company_belong,merchant_id,market_admin_id") ->join("tab_promote as p on s.promote_id = p.id") ->where($where) ->group("relation_game_name,company_id,merchant_id,market_admin_id") ->order("pay_amount desc")->select(); foreach ($dbres as $v) { if(!array_key_exists($v['relation_game_name'],$this->downFlowData[$v['company_id']][$v['market_admin_id']])){ $this->downFlowData[$v['company_id']][$v['market_admin_id']][$v['relation_game_name']] = [ "cp_pay_amount"=>0, "promote_pay_amount"=>0, "pay_amount"=>0, "channel_amount"=>0, "refund_amount"=>0, "special_amount"=>0, "ratio"=>0 ]; } $channel_amount = round($v['pay_amount']*$this->channelRatio[$v['merchant_id']]/100,2); $cp_amount = $v['pay_amount']-$v['refund_amount']; $promote_amount = $v['pay_amount']-$v['refund_amount']; $this->downFlowData[$v['company_id']][$v['market_admin_id']][$v['relation_game_name']]['channel_amount'] += $channel_amount; $this->downFlowData[$v['company_id']][$v['market_admin_id']][$v['relation_game_name']]['cp_pay_amount'] += $cp_amount; $this->downFlowData[$v['company_id']][$v['market_admin_id']][$v['relation_game_name']]['promote_pay_amount'] += $promote_amount; $this->downFlowData[$v['company_id']][$v['market_admin_id']][$v['relation_game_name']]['pay_amount'] += $v['pay_amount']; $this->downFlowData[$v['company_id']][$v['market_admin_id']][$v['relation_game_name']]['refund_amount'] += $v['refund_amount']; } unset($dbres); } /** * 获取游戏信息及cp结算比例 */ private function getAllGameInfo() { $games=[]; foreach ( $this->downFlowData as $key => $market) { foreach ($market as $value) { $games = array_merge(array_keys($value),$games); } } $games = array_unique($games); //获取游戏信息 $gameRes = M("Game","tab_")->where(['relation_game_name'=>['in',$games]])->getField("relation_game_name,relation_game_id",TRUE); foreach ($gameRes as $k => $v) { $this->gameInfo[$k]['relation_game_id'] = $v; $this->gameInfo[$k]['cp_ratio'] = 0; } $this->getCpStatement(); } /** * 获取公司信息及推广员账号,市场员信息 */ private function getCompanyOtherInfo() { $companyIds = array_unique(array_keys($this->downFlowData)); $companyRes = M("promote_company","tab_")->alias("pc") ->join("tab_promote as p on p.company_id = pc.id") ->where(['pc.id'=>['in',$companyIds],'p.level'=>1]) ->group("pc.id") ->getField("pc.id company_id,pc.company_name,pc.company_belong,pc.develop_type,p.id promote_id,p.account promote_account",TRUE); $this->companyInfo = $companyRes; } /** * 获取市场员信息 */ private function getMarketUserInfo() { $userid=[]; foreach ( $this->downFlowData as $key => $value) { $userid = array_merge(array_keys($value),$userid); } $userid = array_unique($userid); $this->marketUserInfo = M("auth_group_access") ->alias("acc") ->where(["acc.uid"=>['in',$userid]]) ->join("sys_member as mem on acc.uid = mem.uid") ->join("sys_auth_group as gro on acc.group_id = gro.id") ->getField("acc.uid,mem.real_name,gro.department_id",true); } /** * 获取下游结算比例,以最后一周的结算比例为最终比例 */ private function getPuStatement() { //1.获取下游周结结算单 $where = [ "_string"=>"statement_begin_time between {$this->beginThismonth} and {$this->endThismonth} OR statement_end_time between {$this->beginThismonth} and {$this->endThismonth}", "company_type"=>2, "withdraw_type"=>['in',"0,1"] ]; $statement_pool = M("company_statement_pool","tab_")->where($where)->order("statement_begin_time desc")->select(); //获取结算分段 $date_arr = []; foreach ($statement_pool as $k => $v) { $tem = [ "statement_begin_time"=>$v['statement_begin_time'], "statement_end_time"=>$v['statement_end_time'], "begin_time"=>date("Y.m.d",$v['statement_begin_time']), "end_time"=>date("Y.m.d",$v['statement_end_time']), "withdraw_type"=>0 ]; if($v['statement_begin_time'] < $this->beginThismonth){ $tem['statement_begin_time'] = $this->beginThismonth; $tem['begin_time'] = date("Y.m.d",$this->beginThismonth); } if($v['statement_end_time'] > $this->endThismonth){ $tem['statement_end_time'] = $this->endThismonth; $tem['end_time'] = date("Y.m.d",$this->endThismonth); } $this->getPuAllStatement($tem,$v); if($v['withdraw_type'] == "0"){ $this->getPuCompanyStatement($tem);//对公周结 } $date_arr[] = $tem; } //2.获取对公的下游 $tem = [ "statement_begin_time"=>$this->beginThismonth, "statement_end_time"=>$this->endThismonth, "begin_time"=>date("Y.m.d",$this->beginThismonth), "end_time"=>date("Y.m.d",$this->endThismonth), "withdraw_type"=>1 ]; $this->getPuCompanyStatement($tem); } /** * 获取所有个人周结 */ private function getPuAllStatement($time,$pool){ $id = $pool['id']; //获取基本信息 $infolist = M("company_statement_info","tab_")->where("pool_id = '{$id}'")->select(); //获取母单 if(!empty($pool['create_lack_ids'])){ $l_ids = $pool['create_lack_ids']; $lack_info = M("company_lack_statement_info","tab_")->where("id in ({$l_ids})")->select(); $infolist =array_merge($infolist,$lack_info); } foreach ($infolist as $v) { $sinfo = json_decode($v['statement_info'],true); foreach ($sinfo as $va) { foreach ($va["game_list"] as $val) { //奖罚不算 if( !array_key_exists($val['game_name'],$this->gameInfo) ){ continue; } //其他计算日期不算 if( ($val['statement_begin_time'] != $time['begin_time']) && ($val['statement_end_time'] != $time['end_time']) ){ continue; } $marketKeys = array_keys($this->downFlowData[$v['company_id']]); foreach ($marketKeys as $marketId) { if(!array_key_exists($val['game_name'],$this->downFlowData[$v['company_id']][$marketId])){ continue; } if($this->downFlowData[$v['company_id']][$marketId][$val['game_name']]["ratio"] == 0){ $this->downFlowData[$v['company_id']][$marketId][$val['game_name']]["ratio"] = $val['ratio']; } } } } } } /** * 对公的下游结算 */ private function getPuCompanyStatement($time) { $where = [ "company_belong"=>["NOT IN",[0,9]], "withdraw_type"=>$time['withdraw_type'] ]; if($time['recount']){ $where['_string'] = "statement_begin_time = {$time['statement_begin_time']} OR statement_end_time = {$time['statement_end_time']}"; }else{ $where['statement_begin_time'] = $time['statement_begin_time']; $where['statement_end_time'] = $time['statement_end_time']; } $res = M("company_statement","tab_")->where($where)->select(); if($res){ foreach ($res as $v) { $sinfo = json_decode($v['statement_info'],true); foreach ($sinfo as $val) { //奖罚不算 if( !array_key_exists($val['game_name'],$this->gameInfo) ){ continue; } //其他计算日期不算 if( ($val['statement_begin_time'] != $time['begin_time']) && ($val['statement_end_time'] != $time['end_time']) ){ continue; } $marketKeys = array_keys($this->downFlowData[$v['company_id']]); foreach ($marketKeys as $marketId) { if(!array_key_exists($val['game_name'],$this->downFlowData[$v['company_id']][$marketId])){ continue; } if($this->downFlowData[$v['company_id']][$marketId][$val['game_name']]["ratio"] == 0){ $this->downFlowData[$v['company_id']][$marketId][$val['game_name']]["ratio"] = $val['ratio']; } } } } } } /** * 特殊补点 */ private function getPuSpecialStatement() { $where = [ "company_belong"=>["NOT IN",[0,9]], "withdraw_type"=>3, "_string"=>"statement_begin_time >= {$this->beginThismonth} and statement_end_time <= {$this->endThismonth}" ]; $res = M("company_statement","tab_")->where($where)->select(); if($res){ foreach ($res as $v) { $sinfo = json_decode($v['statement_info'],true); foreach ($sinfo as $va) { foreach ($va["game_list"] as $val) { //奖罚不算 if( !array_key_exists($val['game_name'],$this->gameInfo) ){ continue; } $marketKeys = array_keys($this->downFlowData[$v['company_id']]); $isMoreUser = count($marketKeys) > 1 ? true :false; // dd($isMoreUser); foreach ($marketKeys as $marketId) { if($isMoreUser){ $sum_money = round($this->downFlowData[$v['company_id']][$marketId][$val['game_name']]['pay_amount']/$val['pay_amount']*$val['sum_money'],2); }else{ $sum_money = $val['sum_money']; } $this->downFlowData[$v['company_id']][$marketId][$val['game_name']]["special_amount"] += $sum_money; } } } } } } //获取cp结算单 private function getCpStatement() { $where = [ "company_belong"=>9, "withdraw_type"=>1, "statement_begin_time"=>$this->beginThismonth, "statement_end_time"=>$this->endThismonth ]; $res = M("company_statement","tab_")->where($where)->select(); if($res){ foreach ($res as $v) { $sinfo = json_decode($v['statement_info'],true); foreach ($sinfo as $val) { //获取真实游戏名 $games = $this->cpOPName2GName($val['game_name'],$v['company_id']); foreach ($games as $game) { if( !array_key_exists($game,$this->gameInfo) ){ continue; } if($v['pay_type'] == 1){ $ratio = $val['first_ratio']; }else{ $ratio = $val['second_ratio']; } $this->gameInfo[$game]['cp_ratio'] = $ratio; } } } } } //结算包名还原游戏名 private function cpOPName2GName($OPName,$company_id) { $where = [ "partner_id"=>$company_id, "_string"=>"original_package_name = '{$OPName}' OR relation_game_name = '{$OPName}'" ]; $game = M("Game","tab_")->field("relation_game_name")->where($where)->group("relation_game_name")->select(); if($game){ return array_column($game,"relation_game_name"); }else{ return [$OPName]; } } /** * 计算相应数据 */ private function performanceSet() { foreach ($this->downFlowData as $company_id => $markerts) { foreach ($markerts as $markertUserId => $games) { $baseArr = $this->companyInfo[$company_id]; $baseArr['pay_time'] = $this->date; $baseArr['is_settlement'] = 1; $baseArr['real_name'] = $this->marketUserInfo[$markertUserId]['real_name']; $baseArr['department_id'] = $this->marketUserInfo[$markertUserId]['department_id']; $baseArr['admin_id'] = $markertUserId; foreach ($games as $k => $v) { $game = $this->gameInfo[$k]; $cp_ratio = $game['cp_ratio']; $tempArr = $baseArr; $tempArr['game_id'] = $game['relation_game_id']; $tempArr['relation_game_id'] = $game['relation_game_id']; $tempArr['game_name'] = $k; $tempArr['pay_amount'] = $v['pay_amount']; $tempArr['cp_amount'] = round($v['cp_pay_amount']*$cp_ratio/100,2); $tempArr['promote_amount'] = round($v['promote_pay_amount']*$v['ratio']/100+$v['special_amount'],2); $tempArr['channel_amount'] = $v['channel_amount']; $tempArr['refund_amount'] = $v['refund_amount']; $tempArr['company_tax'] = round( ($v['pay_amount']-$tempArr['cp_amount']-$tempArr['promote_amount']) * ($this->taxRatio / 100),2 ); $tempArr['company_profit'] = $tempArr['pay_amount']-$tempArr['cp_amount']-$tempArr['promote_amount']-$tempArr['channel_amount']-$tempArr['company_tax']; $tempArr['is_tip'] = 0; if($this->oldMarketPerformance){ if(!array_key_exists($company_id,$this->oldMarketPerformance) || !array_key_exists($k,$this->oldMarketPerformance[$company_id])){ $tempArr['is_tip'] = 1; }else{ if($this->oldMarketPerformance[$company_id][$k]['company_profit'] != $tempArr['company_profit'].''){ $tempArr['is_tip'] = 1; } } } //下游流水不等于就要算毛利 if($v['promote_pay_amount'] != 0){ $this->adddata[]= $tempArr; } } } } } /** * 毛利数据库操作 */ private function settleupMarketorderDbSave() { //删除旧数据 // dd($this->adddata); $this->settleupMarketorderModel->where(['pay_time'=>$this->date])->delete(); $this->settleupMarketorderModel->addAll($this->adddata); } /** * 市场经理计算 */ public function marketManagerSet($count_date) { if(!$this->isInit) $this->configInit($count_date); //获取所有的经理 $MarketEvent = A("Market","Event"); $level = $MarketEvent->getConfig('ManagerLevel'); $this->marketAltogetherModel->where(['pay_time'=>$this->date,'level'=>$level])->delete(); $markertManager = $MarketEvent->getManagerPerformanInfo(); if(!$markertManager) return; foreach ($markertManager as $k => $manager) { //获取毛利统计 $dbres = $this->settleupMarketorderModel->where(['pay_time'=>$this->date,'department_id'=>$manager['department_id']])->field("sum(pay_amount) pay_amount,sum(refund_amount) refund_amount,develop_type")->group('develop_type')->select(); $count = [ 'pay_amount'=>0, 'performance_revenue'=>0, 'appraisal_bonuses'=>0 ]; foreach ($dbres as $k => $v) { $tmpPayAmount = $v['pay_amount']-$v['refund_amount']; $count['pay_amount'] += $tmpPayAmount; if($v['develop_type'] == 3){ $count['appraisal_bonuses'] += $tmpPayAmount; }else{ $count['performance_revenue'] += $tmpPayAmount; } } $config = json_decode($manager['market_percentage'],true); $achievement_bonus = round(($count['appraisal_bonuses']*$config['maintain_appraisal_bonuses_ratio'] + $count['performance_revenue']*$config['appraisal_bonuses_ratio'])/100,2); $baseData = [ 'pay_time'=>$this->date, 'level'=>$level, 'pay_amount' => $count['pay_amount'], 'extend_commission'=> round($achievement_bonus*$config['month_bonus_ratio']/100,2), 'wait_commission' => round($achievement_bonus*(100-$config['month_bonus_ratio'])/100,2), 'create_time'=>time(), 'performance_revenue'=>$count['performance_revenue'], 'appraisal_bonuses'=>$count['appraisal_bonuses'], 'achievement_bonus'=>$achievement_bonus, 'wait_achievement_commission'=>round($achievement_bonus*(100-$config['month_bonus_ratio'])/100,2), 'real_name'=>$manager['real_name'], 'admin_id'=>$manager['uid'], 'nickname'=>$manager['nickname'], 'department_id'=>$manager['department_id'] ]; $res = $this->marketAltogetherModel->add($baseData); echo "marketManagerSet {$manager['real_name']}/{$res}".PHP_EOL; } } /** * 设置每月第一个周一自动重算 */ public function setThisMonthFirstMondayScript() { $d = date('d',time()); if($d != 1){ return ; } // 先取得这个月的 1 号 $scheduleTime = $this->getThisMonthFirstMonday(); $tmdRes = M("cmd_tasks","tab_")->where(['type'=>'MarketPerformanceSet','schedule_time'=>$scheduleTime])->find(); if(!$tmdRes){ $pay_time = date( 'Y-m', strtotime( 'last day of -1 months' ) ); $params = "php ".SUBSITE_INDEX." Timing/caculateMarketStream/time/{$pay_time}"; D("CmdTasks")->addScheduleTask("MarketPerformanceSet",$params,$scheduleTime); } } public function getThisMonthFirstMonday() { $year = date('Y',time()); $m = date('m',time()); $iThisMonthFirst = strtotime("{$year}-{$m}-01 4:00:00"); $dThisDay = date("w", $iThisMonthFirst); if ($dThisDay == '1') { $dFirstMonday = $iThisMonthFirst; }else if($dThisDay < 1){ $dFirstMonday = $iThisMonthFirst + 86400; }else { //不是星期一先回到星期日 $iDays = 86400 * ($dThisDay * 1); //找出星期日的日期 $iSunday = $iThisMonthFirst - $iDays; //星期日 + 8 天就是星期一 $iThisMonthFirstMonday = $iSunday + (86400 * 8); $dFirstMonday = $iThisMonthFirstMonday; } return $dFirstMonday; } }