field("value")->where("`key` = 'aggregate_cp_settlement_api'")->find(); if(empty($cpapihost)){ echo "请先设置请求接口aggregate_cp_settlement_api的值".PHP_EOL;die; } $this->cpapihost = $cpapihost['value']; } public function setFreeDateCount($begin,$end='') { if($end == '') $end = $begin; //判断日期格式 $patten = "/^\d{4}[\-](0?[1-9]|1[012])[\-](0?[1-9]|[12][0-9]|3[01])$/"; if (!preg_match($patten, $begin)) { die("开始时间格式错误"); } if (!preg_match($patten, $end)) { die("结束时间格式错误"); } if(strtotime($end) < strtotime($begin)){ die("结束时间不能比开始时间小"); } if(strtotime($end)+86399-24*3600 > time()){ die("结束时间不能大于当前"); } $starttime = $begin?strtotime($begin):mktime(0,0,0,date('m'),date('d'),date('Y')); $endtime = $end?strtotime($end)+86399:$starttime+86399; $datelist = get_date_list($starttime,$endtime,1); $countdate = count($datelist); for($i=0;$i<$countdate;$i++){ $this->setDailyCount($datelist[$i]); } } public function setDailyCount($stime="now") { if(!IS_CLI){ // die("只支持脚本访问"); } if($stime=="now"){ $stime=time(); }else{ $stime = strtotime($stime); } $nowdate = date("Y-m-d",$stime); $w = (int)date("w",$stime); $d = (int)date("d",$stime); if($w == 1 || $d == 1){ if($w == 1){ echo $nowdate.":".PHP_EOL; echo "--周结begin".PHP_EOL; $this->cpStatement(0,$stime); echo "----CP周结统计ok".PHP_EOL; $this->promoteCompanyStatement(0,$stime); echo "----推广公司周结统计ok".PHP_EOL; } if($d == 1){ echo $nowdate.":".PHP_EOL; echo "--月结&补点begin".PHP_EOL; $this->cpStatement(1,$stime); $this->cpStatement(2,$stime); echo "----CP月结&补点统计ok".PHP_EOL; $this->promoteCompanyStatement(1,$stime); $this->promoteCompanyStatement(2,$stime); echo "----推广公司月结&补点统计ok".PHP_EOL; } }else{ echo $nowdate."非周一和月初,无需任何处理".PHP_EOL; } } /** * 上游结算 * @param [string] $type 0:周结 1:月结 2:周结补点 */ public function cpStatement($type,$stime,$company_id=false) { $t = $this->setBeginAndEndTime($type,$stime);; $begintime = $t[0]; $endtime = $t[1]; if($company_id === false){ //非重算 $where = [ "_string"=>"first_company_type = '1' OR second_company_type = '1'" ]; }else{ $where = [ "_string"=>"(first_company_type = '1' AND first_company_id = '{$company_id}') OR (second_company_type = '1' AND second_company_id = '{$company_id}')" ]; } //获取哪些要结算 if($type == 1){ $where['settlement_type']=2; $cpDbRes = M("CompanyRelation","tab_")->where($where)->select(); }else{ $where['settlement_type']=1; $cpDbRes = M("CompanyRelation","tab_")->where($where)->select(); } $cpList=[]; $js_id = [];//己方公司 foreach ($cpDbRes as $k => $v) { if($v['first_company_type'] == 1){ $cpList[$v['first_company_id']] =$v; $js_id[] =$v['second_company_id']; }else{ $cpList[$v['second_company_id']] =$v; $js_id[] =$v['first_company_id']; } } if(count($js_id) ==0 || count($cpList) == 0){return ;} $cp_id = implode(",",array_flip(array_flip(array_keys($cpList)))); $js_id = implode(",",array_unique($js_id)); //获取cp公司 $tmpp = M("Partner","tab_")->field("id,partner,link_man,link_phone,address,company_tax_no,payee_name,bank_account,opening_bank,channel_rate,invoice_rate,company_type")->where(["id"=>['in',$cp_id]])->select(); $cp =[]; foreach ($tmpp as $v) { $cp[$v['id']]=$v; } unset($tmpp); //获取己方公司 $our = []; $tmpp = M("CompanyInfo","tab_")->field("id,partner,link_man,link_phone,address,company_tax_no,payee_name,bank_account,opening_bank")->where(["id"=>['in',$js_id]])->select(); foreach ($tmpp as $v) { $our[$v['id']]=$v; } unset($tmpp); unset($js_id); //获取本地数据 $locals = $this->getLocalStatementData($begintime,$endtime,$cp_id); //获取聚合数据 $sign = md5($begintime.$endtime."1".$this->token); $arr = [ "begintime"=>$begintime, "endtime"=>$endtime, "type"=>1, "sign"=>$sign, "cp_id"=>$cp_id ]; $dataurl .= $this->cpapihost."&".http_build_query($arr); $html = file_get_contents($dataurl); $rsp = json_decode($html,true); if($rsp['code'] != 1){ echo $rsp['error'].PHP_EOL;die; }else{ $rsp = $rsp['data']; } //整合数据本地 foreach($locals as $k=>$v){ $cpList[$k]["list"] = $v["list"]; } //整合数据,聚合 foreach($rsp as $k=>$v){ if(isset($cpList[$k]["list"])){ //已经存在 foreach($rsp[$k]["list"] as $ke=>$va){ if(isset($cpList[$k]["list"][$ke])){ $cpList[$k]["list"][$ke]['pay_money'] += $va['pay_money']; }else{ $cpList[$k]["list"][$ke] = ["pay_money"=>$va['pay_money']]; } } }else{ $cpList[$k]["list"] = $v["list"]; } } //比例计算及保存 // TODO:此处不判断现游戏名=原包名,但却不是同一款游戏 $verify_log=json_encode(["create_user"=>"system","create_time"=>date("Y-m-d H:i:s")]); $GameDb = M("Game","tab_"); $StatementDb = M("CompanyStatement","tab_"); $statement_begin_time = date("Y-m-d",$begintime); $statement_end_time = date("Y-m-d",$endtime); foreach($cpList as $k=>$v){ $add_data=[]; //1.获取甲乙方信息 if($v['first_company_type'] == 1){ //甲方上游 $cp[$v['first_company_id']]['invoice_type'] = $v['invoice_type']; $cp[$v['first_company_id']]['invoice_content'] = $v['invoice_content']; $add_data['first_party_info'] = json_encode($cp[$v['first_company_id']],JSON_UNESCAPED_UNICODE); $add_data['second_party_info'] = json_encode($our[$v['second_company_id']],JSON_UNESCAPED_UNICODE); $add_data['company_id'] = $v['first_company_id']; $add_data['company_name'] = $v['first_company_name']; }else{ //乙方上游 $cp[$v['second_company_id']]['invoice_type'] = $v['invoice_type']; $cp[$v['second_company_id']]['invoice_content'] = $v['invoice_content']; $add_data['first_party_info'] = json_encode($our[$v['first_company_id']],JSON_UNESCAPED_UNICODE); $add_data['second_party_info'] = json_encode($cp[$v['second_company_id']],JSON_UNESCAPED_UNICODE); $add_data['company_id'] = $v['second_company_id']; $add_data['company_name'] = $v['second_company_name']; } $add_data['pay_type'] = $v['collection']; $add_data['withdraw_type'] = $type; $add_data['statement_begin_time'] = $begintime; $add_data['statement_end_time'] = $endtime; $add_data['statement_money'] = 0; $add_data['pay_amount'] = 0; $add_data['verify_log'] = $verify_log; $add_data['op_time'] =time(); $add_data['statement_info'] =[]; $add_data['company_belong']=9;//上游 $add_data['company_type']=$cp[$add_data['company_id']]['company_type']; $add_data['is_payment']=$v['is_payment']; //获取渠道及发票税率 $promote_ratio = $cp[$add_data['company_id']]['channel_rate'] ?? 0; $fax_ratio = $cp[$add_data['company_id']]['invoice_rate'] ?? 0; //游戏统计 foreach($v['list'] as $ke=>$va){ $game =[]; $game['pay_amount'] =$va['pay_money']; $game['game_name'] =$ke; //获取游戏id及比例 $game_id = $GameDb->where("game_name='{$ke}' OR relation_game_name='{$ke}'")->field("id,relation_game_id")->find(); if(empty($game_id)){ $game['relation_game_id']=0; // $game['sum_money']=0; $tratio = 0; }else{ //获取比例 $game['relation_game_id']=$game_id['relation_game_id']; if($type == 1){ $tratio = getGameCpRadio($game_id['id'],$va['pay_money'],true); }elseif($type == 0){ $tratio = getGameCpRadio($game_id['id'],$va['pay_money'],false); }else{ //补丁 $tratio1 = getGameCpRadio($game_id['id'],$va['pay_money'],true); $tratio2 = getGameCpRadio($game_id['id'],$va['pay_money'],false); $tratio = $tratio1-$tratio2; } } if($v['first_company_type'] == 1){ $game['first_ratio']=$tratio; $game['second_ratio']=100-$tratio; }else{ $game['first_ratio']=100-$tratio; $game['second_ratio']=$tratio; } $add_data['pay_amount'] += $va['pay_money']; $game['sum_money']=round($va['pay_money']*(100-$promote_ratio)*$tratio*(100-$fax_ratio)/(100*100*100),2);//结算金额=平台总额*(1-渠道费)*分成比例*(1-税费费率) $add_data['statement_money'] += $game['sum_money']; $game['fax_ratio']=$fax_ratio; $game['promote_ratio']=$promote_ratio; $game['statement_begin_time']=$statement_begin_time; $game['statement_end_time']=$statement_end_time; $game['statement_type']=0; $add_data['statement_info'][] = $game; } $add_data['platform_amount'] = $add_data['pay_amount']; if($type < 2){ //非补点奖罚 $rrmap = array( "reward_time" => ['between', [$begintime,$endtime]], "company_type"=>1, "company_id"=>$add_data['company_id'] ); $rfres = M("RewardRecord","tab_") ->field(" IFNULL(SUM(CASE WHEN reward_type = 1 THEN money ELSE 0 END),0) as reward_count, IFNULL(SUM(CASE WHEN reward_type = 2 THEN money ELSE 0 END),0) as fine_count ") ->where($rrmap)->find(); if($rfres['reward_count'] > 0){ $reward_count = $rfres['reward_count']; $add_data['statement_info'][] = array( "statement_begin_time"=>$statement_begin_time, "statement_end_time"=>$statement_end_time, 'statement_type'=>2, "game_name"=>"奖励", 'pay_amount'=>$reward_count, 'sum_money'=>$reward_count, ); $add_data['statement_money']+=$reward_count; $add_data['pay_amount']+=$reward_count; } if($rfres['fine_count'] > 0){ $fine_count = $rfres['fine_count']; $add_data['statement_info'][] = array( "statement_begin_time"=>$statement_begin_time, "statement_end_time"=>$statement_end_time, 'statement_type'=>1, "game_name"=>"罚款", 'pay_amount'=>$fine_count, 'sum_money'=>$fine_count, ); $add_data['statement_money'] -= $fine_count; $add_data['pay_amount'] -= $fine_count;; } } $add_data['statement_info'] = json_encode($add_data['statement_info'],JSON_UNESCAPED_UNICODE); if($type == 2 && $add_data['statement_money'] == 0){ //金额为0不补点 continue; } if($add_data['platform_amount'] <= 0){ return; } //添加 if($company_id === false){ //非重算 $StatementDb->add($add_data); }else{ return $add_data; } } } /** * 获取本地上游结算 */ public function getLocalStatementData($begintime,$endtime,$cp_id) { $game_where = "partner_id in ({$cp_id})"; $game = M('game','tab_'); $gameDbRes = $game->field("id,relation_game_name as game_name,partner_id as cp_id,original_package_name")->where($game_where)->select(); $gameList=[]; foreach ($gameDbRes as $k => $v) { $gameList[$v['id']] =$v; } //获取所有id $gmstr = implode(",",array_flip(array_flip(array_column($gameDbRes,'id')))); //获取支付记录 $paywhere = [ "pay_status"=>1, "payed_time"=>["BETWEEN",[$begintime,$endtime]], "game_id"=>["in",$gmstr] ]; $paydb = M('spend','tab_'); $paylist = $paydb->field("game_id,SUM(pay_amount) pay_amount")->where($paywhere)->group("game_id")->select(); if(empty($paylist)){ return []; } //绑定价格 foreach ($paylist as $k => $v) { $gameList[$v['game_id']]['pay_money'] =$v["pay_amount"]; } unset($paylist); //按游戏名称及cp整理数据 $cplList = []; foreach ($gameList as $k => $v) { if($v['pay_money'] <= 0) continue; //0值不发送 if(empty($v['original_package_name'])){ $game_name = $v['game_name']; }else{ $game_name = $v['original_package_name']; } $cp_id = $v['cp_id']; unset($v['cp_id']); $ymoney = $cplList[$cp_id]['list'][$game_name]["pay_money"]?:0; $cplList[$cp_id]['list'][$game_name]["pay_money"] =$ymoney+$v["pay_money"]; // if($type==2){ // $cplList[$cp_id]['list'][$game_name]["list"][] =$v; //传递列表详情 // } } return $cplList; } /** * 下游结算 */ public function promoteCompanyStatement($type,$stime,$company_id=false) { $t = $this->setBeginAndEndTime($type,$stime); $begintime = $t[0]; $endtime = $t[1]; if($company_id === false){ //非重算 $where = [ "_string"=>"first_company_type = '2' OR second_company_type = '2'" ]; }else{ $where = [ "_string"=>"(first_company_type = '2' AND first_company_id = '{$company_id}') OR (second_company_type = '2' AND second_company_id = '{$company_id}')" ]; } //获取哪些要结算 if($type == 1){ $where['settlement_type']=2; $pcDbRes = M("CompanyRelation","tab_")->where($where)->select(); }else{ $where['settlement_type']=1; $pcDbRes = M("CompanyRelation","tab_")->where($where)->select(); } $pcList=[]; $js_id = [];//己方公司 foreach ($pcDbRes as $k => $v) { if($v['first_company_type'] == 2){ $pcList[$v['first_company_id']] =$v; $js_id[] =$v['second_company_id']; }else{ $pcList[$v['second_company_id']] =$v; $js_id[] =$v['first_company_id']; } } $pc_id = implode(",",array_flip(array_flip(array_keys($pcList)))); $js_id = implode(",",array_unique($js_id)); if(count($js_id) ==0 || count($pcList) == 0){ //无需处理 return ; } //获取pc公司 $tmpp = M("PromoteCompany","tab_")->field("id,company_name partner,settlement_contact link_man,contact_phone link_phone,address,bank_address payee_name,bank_card bank_account,fax_ratio,company_belong,company_type")->where(["id"=>['in',$pc_id]])->select(); $pc =[]; foreach ($tmpp as $v) { $pc[$v['id']]=$v; } unset($tmpp); //获取己方公司 $our = []; $tmpp = M("CompanyInfo","tab_")->field("id,partner,link_man,link_phone,address,company_tax_no,payee_name,bank_account,opening_bank")->where(["id"=>['in',$js_id]])->select(); foreach ($tmpp as $v) { $our[$v['id']]=$v; } unset($tmpp); unset($js_id); $this->getPromoteCompanySpend($pcList,array_unique(array_keys($pcList)),$begintime,$endtime); //数据整合 $verify_log=json_encode(["create_user"=>"system","create_time"=>date("Y-m-d H:i:s")]); $StatementDb = M("CompanyStatement","tab_"); $statement_begin_time = date("Y-m-d",$begintime); $statement_end_time = date("Y-m-d",$endtime); foreach($pcList as $k=>$v){ $add_data=[]; //1.获取甲乙方信息 if($v['first_company_type'] == 1){ //甲方上游 $pc[$v['first_company_id']]['invoice_type'] = $v['invoice_type']; $pc[$v['first_company_id']]['invoice_content'] = $v['invoice_content']; $add_data['first_party_info'] = json_encode($pc[$v['first_company_id']],JSON_UNESCAPED_UNICODE); $add_data['second_party_info'] = json_encode($our[$v['second_company_id']],JSON_UNESCAPED_UNICODE); $add_data['company_id'] = $v['first_company_id']; $add_data['company_name'] = $v['first_company_name']; }else{ //乙方上游 $pc[$v['second_company_id']]['invoice_type'] = $v['invoice_type']; $pc[$v['second_company_id']]['invoice_content'] = $v['invoice_content']; $add_data['first_party_info'] = json_encode($our[$v['first_company_id']],JSON_UNESCAPED_UNICODE); $add_data['second_party_info'] = json_encode($pc[$v['second_company_id']],JSON_UNESCAPED_UNICODE); $add_data['company_id'] = $v['second_company_id']; $add_data['company_name'] = $v['second_company_name']; } $add_data['pay_type'] = $v['collection']; $add_data['withdraw_type'] = $type; $add_data['statement_begin_time'] = $begintime; $add_data['statement_end_time'] = $endtime; $add_data['statement_money'] = 0; $add_data['pay_amount'] = 0; $add_data['verify_log'] = $verify_log; $add_data['op_time'] =time(); $add_data['is_payment']=$v['is_payment']; $add_data['statement_info'] =[]; //获取渠道及发票税率 $fax_ratio = $pc[$add_data['company_id']]['fax_ratio'] ?? 0; $company_belong = $pc[$add_data['company_id']]['company_belong']; $add_data['company_belong']=$company_belong; $add_data['company_type']=$pc[$add_data['company_id']]['company_type']; //游戏统计 foreach($v['list'] as $ke=>$va){ $game =[]; $game['pay_amount'] =$va['pay_amount']; $game['game_name'] =$va['game_name']; //获取比例 $game['relation_game_id']=$va['relation_game_id']; if($type == 1){ $tratio = getGamePromoteCompanyRadio($add_data['company_id'],$va['relation_game_id'],$endtime,$va['pay_amount'],true,$company_belong); }elseif($type == 0){ $tratio = getGamePromoteCompanyRadio($add_data['company_id'],$va['relation_game_id'],$endtime,$va['pay_amount'],false,$company_belong); }else{ //补点 $tratio1 = getGamePromoteCompanyRadio($add_data['company_id'],$va['relation_game_id'],$endtime,$va['pay_amount'],true,$company_belong);; $tratio2 = getGamePromoteCompanyRadio($add_data['company_id'],$va['relation_game_id'],$endtime,$va['pay_amount'],false,$company_belong); $tratio = $tratio1-$tratio2; } if($v['type'] == 2){ $game['increment_ratio']=$tratio; }else{ $game['ratio']=$tratio; } $add_data['pay_amount'] += $va['pay_amount']; $game['sum_money']=round($va['pay_amount']*$tratio*(100-$fax_ratio)/(100*100),2);//结算金额=平台总额*(1-渠道费)*分成比例*(1-税费费率) $add_data['statement_money'] += $game['sum_money']; $game['fax_ratio']=$fax_ratio; $game['statement_begin_time']=$statement_begin_time; $game['statement_end_time']=$statement_end_time; $game['statement_type']=0; $add_data['statement_info'][] = $game; } $add_data['platform_amount'] = $add_data['pay_amount']; if($type < 2){ //非补点奖罚 $rrmap = array( "reward_time" => ['between', [$begintime,$endtime]], "company_type"=>2, "company_id"=>$add_data['company_id'] ); $rfres = M("RewardRecord","tab_") ->field(" IFNULL(SUM(CASE WHEN reward_type = 1 THEN money ELSE 0 END),0) as reward_count, IFNULL(SUM(CASE WHEN reward_type = 2 THEN money ELSE 0 END),0) as fine_count ") ->where($rrmap)->find(); if($rfres['reward_count'] > 0){ $reward_count = $rfres['reward_count']; $add_data['statement_info'][] = array( "statement_begin_time"=>$statement_begin_time, "statement_end_time"=>$statement_end_time, 'statement_type'=>2, "game_name"=>"奖励", 'pay_amount'=>$reward_count, 'sum_money'=>$reward_count, ); $add_data['statement_money']+=$reward_count; $add_data['pay_amount']+=$reward_count; } if($rfres['fine_count'] > 0){ $fine_count = $rfres['fine_count']; $add_data['statement_info'][] = array( "statement_begin_time"=>$statement_begin_time, "statement_end_time"=>$statement_end_time, 'statement_type'=>1, "game_name"=>"罚款", 'pay_amount'=>$fine_count, 'sum_money'=>$fine_count, ); $add_data['statement_money'] -= $fine_count; $add_data['pay_amount'] -= $fine_count;; } } $add_data['statement_info'] = json_encode($add_data['statement_info'],JSON_UNESCAPED_UNICODE); if($type == 2 && $add_data['statement_money'] == 0){ //金额为0不补点 continue; } if($add_data['platform_amount'] <= 0){ return; } //添加 if($company_id === false){ //非重算 $StatementDb->add($add_data); }else{ return $add_data; } } } //设定开始结束时间 protected function setBeginAndEndTime($type,$stime){ if($type == 0){ $begintime = mktime(0,0,0,date('m',$stime),date('d',$stime)-7,date('Y',$stime)); $endtime = mktime(0,0,0,date('m',$stime),date('d',$stime),date('Y',$stime))-1; }else{ $thismonth = date('m',$stime); $thisyear = date('Y',$stime); if ($thismonth == 1) { $lastmonth = 12; $lastyear = $thisyear - 1; } else { $lastmonth = $thismonth - 1; $lastyear = $thisyear; } $lastStartDay = $lastyear . '-' . $lastmonth . '-1'; $lastEndDay = $lastyear . '-' . $lastmonth . '-' . date('t', strtotime($lastStartDay)); $begintime = strtotime($lastStartDay);//上个月的月初时间戳 $endtime = strtotime($lastEndDay)+24*3600-1;//上个月的月末时间戳 } return [$begintime,$endtime]; } //获取推广公司推广金额 protected function getPromoteCompanySpend(&$pcList,$idarr,$begintime,$endtime){ $res = []; //获取推广员 if(count($idarr) == 0){return $res;} $Promote = M("Promote","tab_"); $Spend = M("Spend","tab_"); $spenMap = [ "s.pay_status"=>1, "s.pay_time"=>['between', [$begintime,$endtime]], ]; for ($i=0; $i field("group_concat(id) ids,count(id) count")->where("company_id = '{$company_id}'")->group("company_id")->find(); if($pres['count'] ==0 ){continue;} $spenMap['s.promote_id']=["in",$pres['ids']]; //获取支付记录 $list = $Spend->alias('s')->field('sum(s.pay_amount) pay_amount,s.game_id,g.relation_game_id,g.relation_game_name game_name')->where($spenMap)->group('game_id') ->join("tab_game g on s.game_id = g.id") ->select(); if(empty($list)){continue;} foreach($list as $k=>$v){ if(isset($res[$company_id][$v['relation_game_id']])){ // $res[$company_id][$v['relation_game_id']]['pay_amount'] += $v['pay_amount']; }else{ unset($v['game_id']); $res[$company_id][$v['relation_game_id']]= $v; } } } foreach($res as $k=>$v){ $pcList[$k]['list'] = $v; } } /** * 重算接口 * 不进行结算方式重算 * @param [type] $id 原数据id * @param string $admin_user 操作用户 * @return void bool */ public function updateCompanyStatementData($id,$admin_user='system') { //获取数据 $StatementDb = M("CompanyStatement","tab_"); $dbres = $StatementDb->where("id='{$id}'")->find(); //获取时间 $stime = $dbres['statement_end_time']-0+1; $company_id = $dbres['company_id']; if($dbres['company_belong'] == 9){ //上游 $savedata = $this->cpStatement($dbres['withdraw_type'],$stime,$company_id); }else{ $savedata = $this->promoteCompanyStatement($dbres['withdraw_type'],$stime,$company_id); } //重写用户 $savedata['verify_log'] = json_encode(["create_user"=>$admin_user,"create_time"=>date("Y-m-d H:i:s")]); $savedata['verify_status'] = 0; $savedata['id'] = $dbres['id']; return $StatementDb->save($savedata); } }