You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

600 lines
20 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace Admin\Controller;
use Think\Controller;
/**
* 聚合渠道结算接口对接
* @author cz
*/
class CompanyStatementSetController extends Controller {
public $cpapihost;
public $token = "LYHTQDJS";
public function _initialize(){
$cpapihost = M("Kv")->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;
}
}
/**
* TODO:渠道费未进行计算
* 上游结算
* @param [string] $type 0:周结 1:月结 2周结补点
*/
public function cpStatement($type,$stime)
{
$t = $this->setBeginAndEndTime($type,$stime);;
$begintime = $t[0];
$endtime = $t[1];
//获取哪些要结算
if($type == 1){
$cpDbRes = M("CompanyRelation","tab_")->where("settlement_type = 2 AND (first_company_type = '1' OR second_company_type = '1')")->select();
}else{
$cpDbRes = M("CompanyRelation","tab_")->where("settlement_type = 1 AND (first_company_type = '1' OR second_company_type = '1')")->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")->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"=>$_SESSION['onethink_admin']['user_auth']["username"],"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){
//甲方上游
$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{
//乙方上游
$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'] =[];
//获取渠道及发票税率
$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;
}
//添加
$StatementDb->add($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)
{
$t = $this->setBeginAndEndTime($type,$stime);
$begintime = $t[0];
$endtime = $t[1];
//获取哪些要结算
if($type == 1){
$pcDbRes = M("CompanyRelation","tab_")->where("settlement_type = 2 AND (first_company_type = '2' OR second_company_type = '2')")->select();
}else{
$pcDbRes = M("CompanyRelation","tab_")->where("settlement_type = 1 AND (first_company_type = '2' OR second_company_type = '2')")->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 opening_bank,bank_card bank_account,fax_ratio,company_belong")->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"=>$_SESSION['onethink_admin']['user_auth']["username"],"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){
//甲方上游
$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{
//乙方上游
$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['statement_info'] =[];
//获取渠道及发票税率
$fax_ratio = $pc[$add_data['company_id']]['fax_ratio'] ?? 0;
$company_belong = $pc[$add_data['company_id']]['company_belong'];
//游戏统计
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['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_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;
}
//添加
$StatementDb->add($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 <count($idarr); $i++) {
$company_id = $idarr[$i];
$pres = $Promote->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;
}
}
}