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.

543 lines
23 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 GameMarginSetController extends Controller {
private $beginThismonth;
private $endThismonth;
private $date;
private $nowdata;
private $month;//月份
private $year;//年份
private $adddata;//要添加的数据
private $inSideCompanyIds;
private $downFlowData;
/**
* 更新某月数据
*/
public function setFreeMonth($count_date)
{
//设置转换精度
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->reCount();
$this->setGameMargin();
}
/**
* 强制重新聚合
*/
private function reCount()
{
$recount = I("recount");
if(empty($recount) || $recount != 1){return ;}
//清理之前的聚合
$temp =array(
"count_year"=>$this->year,
"count_month"=>$this->month
);
M("GameMargin","tab_")->where($temp)->delete();
echo "旧数据清理成功".PHP_EOL;
}
private function setGameMargin()
{
$this->getInsideCompanyid();
//获取所有下游支付信息
$this->getAllDownFlowSpend();
$this->getAllGameSpend();
$this->getJuheStatement();
$this->getCpStatement();
$this->getPuStatement();
$this->getPcStatement();
//计算内外团数据
$this->setDownFlowCount();
//3.特殊补点
$this->getPuSpecialStatement();
$this->setMarginCount();
echo "{$this->year}-{$this->month}生成成功".PHP_EOL;
}
/**
* 内部公司
*/
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);
}
//获取期间下游公司游戏流水
private function getAllDownFlowSpend()
{
$where = [
"pay_status"=>1,
"is_refund"=>0,
"is_check"=>1,
"payed_time"=>["between",[$this->beginThismonth,$this->endThismonth]],
"p.company_id"=>["NOT IN",$this->inSideCompanyIds]
];
$dbres = M("Spend","tab_")
->alias("s")
->field("substring_index(game_name, '(', 1) relation_game_name,SUM(pay_amount) pay_amount,p.company_id,p.company_belong")
->join("tab_promote as p on s.promote_id = p.id")
->where($where)
->group("relation_game_name,company_id")
->order("pay_amount desc")->select();
foreach ($dbres as $v) {
if($v['company_belong'] > 0){
$v['company_belong'] = 1;
}else{
$v['company_belong'] = 0;
}
$this->downFlowData[$v['company_belong']][$v['company_id']][$v['relation_game_name']]['pay_amount'] = $v['pay_amount'];
}
unset($dbres);
}
//获取期间所有有流水的游戏
private function getAllGameSpend()
{
$where = [
"pay_status"=>1,
"pay_game_status"=>1,
"is_refund"=>0,
"payed_time"=>["between",[$this->beginThismonth,$this->endThismonth]]
];
$this->adddata = M("Spend","tab_")->where($where)->group("relation_game_name")->order("pay_amount desc")->getField("substring_index(game_name, '(', 1) relation_game_name,SUM(pay_amount) pay_amount",true);
}
/**
* 获取聚合数据
* 688是官方渠道需要剔除
*/
private function getJuheStatement()
{
$where = [
"begintime"=>["between",[$this->beginThismonth,$this->endThismonth]],
"channel_id"=>["NOT IN",[688]],
"pay_money"=>['GT',0]
];
$dbres = M("aggregate_statement","tab_")->field('statement_info')->where($where)->select();
if(!empty($dbres)){
foreach ($dbres as $k => $v) {
$statement_info = json_decode($v['statement_info'],true);
foreach ($statement_info as $key => $val) {
if(array_key_exists($val['game_name'],$this->adddata)){
$this->adddata[$val['game_name']]['pay_amount'] += $val['money'];
if( array_key_exists("jh_pay_amount",$this->adddata[$val['game_name']]) ){
$this->adddata[$val['game_name']]['jh_pay_amount'] += $val['money'];
$this->adddata[$val['game_name']]['jh_statement_amount'] += $val['ratio_money'];
}else{
$this->adddata[$val['game_name']]['jh_pay_amount'] = $val['money'];
$this->adddata[$val['game_name']]['jh_statement_amount'] = $val['ratio_money'];
}
}else{
$this->adddata[$val['game_name']] = [
"relation_game_name"=>$val['game_name'],
"pay_amount"=>$val['money'],
"jh_pay_amount"=>$val['money'],
"jh_statement_amount"=>$val['ratio_money']
];
}
}
}
}
}
/**
* 获取下游外团结算数据
* 当前外团:个人周结结算与少部分对月结算
* @TODO: 万一内团也周结,这里的逻辑需要更改,目前所有的周结都算外团
*/
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"=>0
];
$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);
$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->adddata) ){
continue;
}
//其他计算日期不算
if( ($val['statement_begin_time'] != $time['begin_time']) && ($val['statement_end_time'] != $time['end_time']) ){
continue;
}
if(!array_key_exists($val['game_name'],$this->downFlowData[1][$v['company_id']])){
continue;
}
if(!array_key_exists("ratio",$this->downFlowData[1][$v['company_id']][$val['game_name']])){
$this->downFlowData[1][$v['company_id']][$val['game_name']]["ratio"] = $val['ratio'];
}
}
}
}
}
//按推广员及游戏名称获取支付合计
private function getPuGameSpend($account,$game_name,$begin,$end){
//获取全部推广员
$id = M("promote","tab_")->field("id")->where("account = '{$account}'")->find()['id'];
//获取全部推广员
$ids = M("promote","tab_")->field("group_concat(id) ids")->where("level1_id = '{$id}'")->group("level1_id")->find()['ids'];
$where = [
"pay_status"=>1,
"payed_time"=>["between",[$begin,$end]],
"promote_id"=>["in",$ids],
"game_name"=>["like",$game_name."%"]
];
return M("Spend","tab_")->where($where)->field("SUM(pay_amount) pay_amount")->find()['pay_amount'];
}
//按公司及游戏名称获取支付合计
private function getPuCompanyGameSpend($company_id,$game_name,$begin,$end){
//获取全部推广员
$ids = M("promote","tab_")->field("group_concat(id) ids")->where("company_id = '{$company_id}'")->group("company_id")->find()['ids'];
$where = [
"pay_status"=>1,
"payed_time"=>["between",[$begin,$end]],
"promote_id"=>["in",$ids],
"game_name"=>["like",$game_name."%"]
];
return M("Spend","tab_")->where($where)->field("SUM(pay_amount) pay_amount")->find()['pay_amount'];
}
/**
* 对公的下游结算
*/
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->adddata) ){
continue;
}
//其他计算日期不算
if( ($val['statement_begin_time'] != $time['begin_time']) && ($val['statement_end_time'] != $time['end_time']) ){
continue;
}
if(!array_key_exists($val['game_name'],$this->downFlowData[1][$v['company_id']])){
continue;
}
if(!array_key_exists("ratio",$this->downFlowData[1][$v['company_id']][$val['game_name']])){
$this->downFlowData[1][$v['company_id']][$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->adddata) ){
continue;
}
if( array_key_exists("pu_statement_amount",$this->adddata[$val['game_name']]) ){
$this->adddata[$val['game_name']]['pu_statement_amount'] += $val['sum_money'];
}else{
$this->adddata[$val['game_name']]['pu_statement_amount'] = $val['sum_money'];
}
if($this->debugGame && $this->debugGame == $val['game_name']){
$beginThismonth = date("Y.m.d",$this->beginThismonth);
$endThismonth = date("Y.m.d",$this->endThismonth);
$this->debugStr .= (PHP_EOL."{$v['company_name']},外团,{$beginThismonth}-{$endThismonth},0,{$val['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->adddata) ){
continue;
}
if($v['pay_type'] == 1){
$ratio = $val['first_ratio'];
}else{
$ratio = $val['second_ratio'];
}
$statement_money = round( $this->adddata[$game]['pay_amount'] / $val['pay_amount'] * $val['sum_money'],2);
if( array_key_exists("cp_statement_amount",$this->adddata[$game]) ){
$this->adddata[$game]['cp_statement_amount'] += $statement_money;
}else{
$this->adddata[$game]['cp_statement_amount'] = $statement_money;
}
$this->adddata[$game]['cp_promote_ratio'] = $val['promote_ratio'];
$this->adddata[$game]['cp_ratio'] = $ratio;
}
}
}
}
}
//结算包名还原游戏名
private function cpOPName2GName($OPName,$company_id)
{
$where = [
"partner_id"=>$company_id,
"_string"=>"( original_package_name = '{$OPName}' AND select_package_name = 0 ) OR ( relation_game_name = '{$OPName}' AND select_package_name = 1 )"
];
$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 getPcStatement()
{
$where = [
"company_belong"=>0,
"withdraw_type"=>1,
"statement_begin_time"=>$this->beginThismonth,
"statement_end_time"=>$this->endThismonth,
"company_id"=>["NOT IN",$this->inSideCompanyIds]
];
$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->adddata) ){
continue;
}
if(!array_key_exists($val['game_name'],$this->downFlowData[0][$v['company_id']])){
continue;
}
if(!array_key_exists("ratio",$this->downFlowData[1][$v['company_id']][$val['game_name']])){
$this->downFlowData[0][$v['company_id']][$val['game_name']]["ratio"] = $val['ratio'];
}
}
}
}
}
private function setDownFlowCount()
{
$insideGroup = $this->downFlowData[0];
$outGroup = $this->downFlowData[1];
foreach ($insideGroup as $companyId => $gameList) {
foreach ($gameList as $gameName => $v) {
$v['sum_money'] = round($v['pay_amount']*$v['ratio']/100,2);
if( array_key_exists("pc_pay_amount",$this->adddata[$gameName]) ){
$this->adddata[$gameName]['pc_pay_amount'] += $v['pay_amount'];
$this->adddata[$gameName]['pc_statement_amount'] += $v['sum_money'];
}else{
$this->adddata[$gameName]['pc_pay_amount'] = $v['pay_amount'];
$this->adddata[$gameName]['pc_statement_amount'] = $v['sum_money'];
}
}
}
foreach ($outGroup as $companyId => $gameList) {
foreach ($gameList as $gameName => $v) {
$v['sum_money'] = round($v['pay_amount']*$v['ratio']/100,2);
if( array_key_exists("pu_pay_amount",$this->adddata[$gameName]) ){
$this->adddata[$gameName]['pu_pay_amount'] += $v['pay_amount'];
$this->adddata[$gameName]['pu_statement_amount'] += $v['sum_money'];
}else{
$this->adddata[$gameName]['pu_pay_amount'] = $v['pay_amount'];
$this->adddata[$gameName]['pu_statement_amount'] = $v['sum_money'];
}
}
}
}
//相关属性计算
private function setMarginCount()
{
$baseCell = [
"jh_pay_amount"=>0,
"jh_statement_amount"=>0,
"jh_ratio"=>0,
"jh_margin_amount"=>0,
"jh_margin_ratio"=>0,
"pu_pay_amount"=>0,
"pu_statement_amount"=>0,
"pu_ratio"=>0,
"pu_margin_amount"=>0,
"pu_margin_ratio"=>0,
"pc_pay_amount"=>0,
"pc_statement_amount"=>0,
"pc_ratio"=>0,
"pc_margin_amount"=>0,
"pc_margin_ratio"=>0,
"pay_amount"=>0,
"cp_statement_amount"=>0,
"cp_promote_ratio"=>0,
"cp_rebate_ratio"=>0,
"cp_rebate_amount"=>0,
"cp_other_amount"=>0,
];
$margin_amount = 0;
$pay_amount = 0;
foreach ($this->adddata as &$v) {
foreach ($baseCell as $bkey=>$bval) array_key_exists($bkey,$v) ?: $v[$bkey] = $bval;
// $v["cp_ratio"] = round($v["cp_statement_amount"]/$v['pay_amount'],4)*100;
//K3*(1-(1-E3)*F3-L3)
if($v["pc_pay_amount"] > 0){
$v["pc_ratio"] = round($v["pc_statement_amount"]/$v['pc_pay_amount'],2)*100;
// $v["pc_margin_amount"] = round($v["pc_pay_amount"]*(1-$v['cp_promote_ratio']/100)*(100-$v["cp_ratio"]-$v['cp_rebate_ratio']-$v["pc_ratio"])/100,2);
$v["pc_margin_amount"] = round($v["pc_pay_amount"]*(1-(100-$v['cp_promote_ratio'])/100*$v['cp_ratio']/100-$v['pc_ratio']/100),2);
$v["pc_margin_ratio"] = round($v["pc_margin_amount"]/$v['pc_pay_amount'],3)*100;
}
if ($v["pu_pay_amount"] > 0) {
$v["pu_ratio"] = round($v["pu_statement_amount"]/$v['pu_pay_amount'],2)*100;
$v["pu_margin_amount"] = round($v["pu_pay_amount"]-$v["pu_pay_amount"]*(1-$v['cp_promote_ratio']/100)*($v["cp_ratio"]+$v['cp_rebate_ratio'])/100-$v["pu_statement_amount"],2);
$v["pu_margin_ratio"] = round($v["pu_margin_amount"]/$v['pu_pay_amount'],3)*100;
}
$v['platform_margin_ratio'] = round(($v['pay_amount']-$v['jh_pay_amount']-$v['cp_statement_amount']-$v['cp_rebate_amount']-$v['cp_other_amount']-$v['pc_statement_amount']-$v['pu_statement_amount'])/($v['pay_amount']-$v['jh_pay_amount']),3)*100;
if($v['jh_pay_amount'] > 0){
$v["jh_ratio"] = round($v["jh_statement_amount"]/$v['jh_pay_amount'],2)*100;
$v["jh_margin_amount"] = round( $v["jh_statement_amount"]-$v["jh_pay_amount"]*(1-$v['cp_promote_ratio']/100)*($v["cp_ratio"]+$v['cp_rebate_ratio'])/100 ,2);
$v["jh_margin_ratio"] = round($v["jh_margin_amount"]/$v['jh_pay_amount'],3)*100;
}
$v['margin_amount'] = round( ($v['pay_amount']-$v['cp_statement_amount']-$v['cp_rebate_amount']-$v['cp_other_amount']-$v['pc_statement_amount']-$v['pu_statement_amount']-( $v['jh_pay_amount'] - $v['jh_statement_amount'] )),2);
$v['margin_ratio'] = round($v['margin_amount']/$v['pay_amount'],3)*100;
$pay_amount += $v['pay_amount'];
$margin_amount += $v['margin_amount'];
}
$margin_ratio = round( $margin_amount/$pay_amount ,3)*100;
//保存数据库
$adddata = [
"margin_ratio"=>$margin_ratio,
"margin_amount"=>$margin_amount,
"pay_amount"=>$pay_amount,
"margin_info"=>json_encode(array_values($this->adddata),JSON_UNESCAPED_UNICODE),
"count_month"=>$this->month,
"count_year"=>$this->year,
"create_time"=>time()
];
M("GameMargin","tab_")->add($adddata);
}
}