Files
2025-03-05 14:02:29 +09:00

425 lines
18 KiB
PHP

<?php
namespace App\Controllers\Api;
use App\Controllers\BaseController;
use App\Libraries\Calc;
use App\Models\Advertiser\AdvFacebookManagerModel;
use App\Models\Advertiser\AdvGoogleManagerModel;
use App\Models\Advertiser\AdvKakaoManagerModel;
use App\Models\Advertiser\AdvManagerModel;
use App\Models\Api\CompanyModel;
use CodeIgniter\API\ResponseTrait;
class RestaController extends BaseController
{
use ResponseTrait;
protected $admanager, $facebook, $google, $kakao;
private $advertiser = [
'더스퀘어치과의원',
'메이드영성형외과의원',
'리프톤피부과의원',
'모아만의원',
'모우림의원',
'열정치과의원',
'우리들40플란트치과병원',
'하루플란트치과의원광고주',
'한나이브성형외과의원',
'강남애프터치과의원',
'참좋은치과의원',
'보가치과의원'
];
public function __construct()
{
$this->admanager = model(AdvManagerModel::class);
$this->facebook = model(AdvFacebookManagerModel::class);
$this->google = model(AdvGoogleManagerModel::class);
$this->kakao = model(AdvKakaoManagerModel::class);
}
public function getList()
{
if(strtolower($this->request->getMethod()) === 'get'){
$arg = $this->request->getGet();
if(empty($arg['external']) || $arg['external'] != 'resta'){
return $this->fail("잘못된 요청");
}
$company = model(CompanyModel::class);
$companySeq = $company->getCompaniesByName($this->advertiser);
$ids = array_column($companySeq, 'id');
$ids = implode("|", $ids);
$arg['searchData']['resta'] = $ids;
switch ($arg['searchData']['type']) {
case 'ads':
$result = $this->getAds($arg);
break;
case 'adsets':
$result = $this->getAdSets($arg);
break;
case 'campaigns':
$result = $this->getCampaigns($arg);
break;
default:
return $this->fail("잘못된 요청");
}
$orderBy = [];
if(!empty($arg['order'])) {
foreach($arg['order'] as $row) {
if($row['dir'] == 'desc'){
$sort = SORT_DESC;
}else{
$sort = SORT_ASC;
}
$col = $arg['columns'][$row['column']]['data'];
if($col) $orderBy[$col] = $sort;
}
array_sort_by_multiple_keys($result['data'], $orderBy);
}
foreach ($result['data'] as &$value) {
$value['bidamount'] = number_format($value['bidamount']);
$value['budget'] = number_format($value['budget']);
$value['impressions'] = number_format($value['impressions']);
$value['click'] = number_format($value['click']);
$value['spend'] = number_format($value['spend']);
$value['sales'] = number_format($value['sales']);
$value['unique_total'] = number_format($value['unique_total']);
$value['margin'] = number_format($value['margin']);
$value['margin_ratio'] = number_format($value['margin_ratio']);
$value['cpa'] = number_format($value['cpa']);
$value['cpc'] = number_format($value['cpc']);
}
if(isset($arg['noLimit'])) {
return $this->respond($result['data']);
}
$result['accounts'] = $this->getAccounts($arg);
$result['media_accounts'] = $this->getMediaAccounts($arg);
$result['report'] = $this->getReport($arg);
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
private function getAccounts($arg)
{
$result = [];
$accounts = $this->admanager->getAccounts($arg);
//$accounts = $this->setAccountData($accounts);
$result = array_merge($result, $accounts);
return $result;
}
private function getMediaAccounts($arg)
{
$result = $this->admanager->getMediaAccounts($arg);
return $result;
}
private function getReport($arg)
{
$result = $this->admanager->getReport($arg);
$columnIndex = 0;
$data = [];
foreach($result as $row) {
$data[] = $row;
foreach ($row as $col => $val) {
if ($val == NULL) $val = "0";
$total[$col][$columnIndex] = $val;
}
$columnIndex++;
}
$report['impressions_sum'] = $report['clicks_sum'] = $report['click_ratio_sum'] = $report['spend_sum'] = $report['unique_total_sum'] = $report['unique_one_price_sum'] = $report['conversion_ratio_sum'] = $report['profit_sum'] = $report['per_sum'] = $report['price_sum'] = $report['spend_ratio_sum'] =$report['cpc'] = 0;
if(!empty($result)){
$report['impressions_sum'] = array_sum($total['impressions']); //총 노출수
$report['clicks_sum'] = array_sum($total['click']); //총 클릭수
if ($report['clicks_sum'] != 0 && $report['impressions_sum'] != 0) {
$report['click_ratio_sum'] = round(($report['clicks_sum'] / $report['impressions_sum']) * 100, 2); //총 클릭률
}
$report['spend_sum'] = array_sum($total['spend']); //총 지출액
$report['spend_ratio_sum'] = floor(array_sum($total['spend']) * 0.85); //총 매체비
if ($report['clicks_sum'] != 0) {
$report['cpc'] = round($report['spend_sum'] / $report['clicks_sum'], 2);
} else {
$report['cpc'] = 0;
}
$report['unique_total_sum'] = array_sum($total['unique_total']); //총 유효db수
if ($report['spend_sum'] != 0 && $report['unique_total_sum'] != 0) {
$report['unique_one_price_sum'] = round($report['spend_sum'] / $report['unique_total_sum'], 0); //총 db당 단가
}
if ($report['unique_total_sum'] != 0 && $report['clicks_sum'] != 0) {
$report['conversion_ratio_sum'] = round(($report['unique_total_sum'] / $report['clicks_sum']) * 100, 2); //총 전환율
}
$report['price_sum'] = array_sum($total['price']); //총 매출액
$report['profit_sum'] = array_sum($total['profit']); //총 수익
if ($report['profit_sum'] != 0 && $report['price_sum'] != 0) {
$report['per_sum'] = round(($report['profit_sum'] / $report['price_sum']) * 100, 2); //총 수익률
}
$report['impressions_sum'] = number_format($report['impressions_sum']);
$report['clicks_sum'] = number_format($report['clicks_sum']);
$report['spend_sum'] = number_format($report['spend_sum']);
$report['unique_one_price_sum'] = number_format($report['unique_one_price_sum']);
$report['spend_ratio_sum'] = number_format($report['spend_ratio_sum']);
$report['price_sum'] = number_format($report['price_sum']);
$report['profit_sum'] = number_format($report['profit_sum']);
}
return $report;
}
private function getCampaigns($arg)
{
$campaigns = $this->admanager->getCampaigns($arg);
$campaigns = $this->setData($campaigns);
$total = $this->getTotal($campaigns);
$result = [
'total' => $total,
'data' => $campaigns,
];
return $result;
}
private function getAdSets($arg)
{
$result = [];
$campaigns = $this->admanager->getAdSets($arg);
$campaigns = $this->setData($campaigns);
$result = array_merge($result, $campaigns);
$total = $this->getTotal($result);
$result = [
'total' => $total,
'data' => $result,
];
return $result;
}
private function getAds($arg)
{
$result = [];
$campaigns = $this->admanager->getAds($arg);
$campaigns = $this->setData($campaigns);
$result = array_merge($result, $campaigns);
$total = $this->getTotal($result);
$result = [
'total' => $total,
'data' => $result,
];
return $result;
}
private function setData($result)
{
foreach ($result as &$row) {
$row['status'] = $this->setStatus($row['status']);
$row['margin_ratio'] = Calc::margin_ratio($row['margin'], $row['sales']); // 수익률
$row['cpc'] = Calc::cpc($row['spend'], $row['click']); // 클릭당단가 (1회 클릭당 비용)
$row['ctr'] = Calc::ctr($row['click'], $row['impressions']); // 클릭율 (노출 대비 클릭한 비율)
$row['cpa'] = Calc::cpa($row['unique_total'], $row['spend']); //DB단가(전환당 비용)
$row['cvr'] = Calc::cvr($row['unique_total'], $row['click']); //전환율
if($row['bidamount_type'] == 'cpm' && $row['bidamount'] <= 1){
$row['bidamount_type'] = '';
$row['bidamount'] = 0;
}
if(!empty($row['biddingStrategyType'])){
switch($row['biddingStrategyType']) {
case 'TARGET_CPA' :
$row['biddingStrategyType'] = '타겟 CPA';
break;
case 'TARGET_ROAS' :
$row['biddingStrategyType'] = '타겟 광고 투자수익(ROAS)';
break;
case 'TARGET_SPEND' :
$row['biddingStrategyType'] = '클릭수 최대화';
break;
case 'MAXIMIZE_CONVERSIONS' :
$row['biddingStrategyType'] = '전환수 최대화';
break;
/* //값이 뭔지 모름ㅠㅠ
case '' :
$row['biddingStrategyType'] = '검색 결과 위치 타겟';
break;
case '' :
$row['biddingStrategyType'] = '경쟁 광고보다 내 광고가 높은 순위에 게재되는 비율 타겟';
break;
case '' :
$row['biddingStrategyType'] = '타겟 노출 점유율';
break;
*/
case 'PAGE_ONE_PROMOTED' :
$row['biddingStrategyType'] = '향상된 CPC 입찰기능';
break;
case 'MANUAL_CPM' :
$row['biddingStrategyType'] = '수동 입찰 전략';
break;
case 'MANUAL_CPC' :
$row['biddingStrategyType'] = '수동 CPC';
break;
case 'UNKNOWN' :
$row['biddingStrategyType'] = '알수없음';
break;
default :
break;
}
}
}
return $result;
}
private function setStatus($status)
{
/*
ON = 인정,
READY = 집행 예정,
FINISHED = 집행 완료,
STOPPED = 정지,
ARCHIVED = 보관,
DELETED = 삭제
UNKNOWN = 알수 없음
UNSPECIFIED = 명시되지 않음
EXCEED_DAILY_BUDGET = 일 예산 초과
NO_AVAILABLE_CREATIVE = 집행 가능한 소재가 없음
CANCELED = 계약 해지
SYSTEM_CONFIG_EXTERNAL_SERVICE_STOP = 연결 서비스 제한으로 운영불가인 상태
ADACCOUNT_UNAVAILABLE = 광고계정 운영불가
CAMPAIGN_UNAVAILABLE = 캠페인 운영불가
ADGROUP_UNAVAILABLE = 광고 상위단위인 광고그룹이 운영불가인 상태
SYSTEM_CONFIG_ADMIN_STOP = 관리자 정지
OPERATING = 운영가능 상태
UNAPPROVED = 심사승인이 아닌 상태(심사중, 심사보류를 모두 포함)
INVALID_DATE = 집행기간이 도래하지 않았거나 이미 지난 상태
MONITORING_REJECTED = 관리자정지 상태
SYSTEM_CONFIG_VOID = 소재 콘텐츠 오류로 소재 운영불가인 상태
*/
if(!empty($status)){
if(in_array($status, ['ENABLED', 'ACTIVE', 'LIVE', 'ON'])){$status = 'ON';}
else if(in_array($status, ['READY'])){$status = 'READY';}
else if(in_array($status, ['FINISHED'])){$status = 'FINISHED';}
else if(in_array($status, ['OFF', 'PAUSED'])){$status = 'OFF';}
else if(in_array($status, ['ARCHIVED'])){$status = 'ARCHIVED';}
else if(in_array($status, ['DELETED', 'REMOVED'])){$status = 'DELETED';}
else if(in_array($status, ['UNKNOWN'])){$status = 'UNKNOWN';}
else if(in_array($status, ['UNSPECIFIED'])){$status = 'UNSPECIFIED';}
else if(in_array($status, ['EXCEED_DAILY_BUDGET'])){$status = 'EXCEED_DAILY_BUDGET';}
else if(in_array($status, ['NO_AVAILABLE_CREATIVE'])){$status = 'NO_AVAILABLE_CREATIVE';}
else if(in_array($status, ['CANCELED'])){$status = 'CANCELED';}
else if(in_array($status, ['SYSTEM_CONFIG_EXTERNAL_SERVICE_STOP'])){$status = 'SYSTEM_CONFIG_EXTERNAL_SERVICE_STOP';}
else if(in_array($status, ['ADACCOUNT_UNAVAILABLE'])){$status = 'ADACCOUNT_UNAVAILABLE';}
else if(in_array($status, ['CAMPAIGN_UNAVAILABLE'])){$status = 'CAMPAIGN_UNAVAILABLE';}
else if(in_array($status, ['SYSTEM_CONFIG_ADMIN_STOP'])){$status = 'SYSTEM_CONFIG_ADMIN_STOP';}
else if(in_array($status, ['OPERATING'])){$status = 'OPERATING';}
else if(in_array($status, ['UNAPPROVED'])){$status = 'UNAPPROVED';}
else if(in_array($status, ['INVALID_DATE'])){$status = 'INVALID_DATE';}
else if(in_array($status, ['MONITORING_REJECTED'])){$status = 'MONITORING_REJECTED';}
else if(in_array($status, ['ADGROUP_UNAVAILABLE'])){$status = 'ADGROUP_UNAVAILABLE';}
else if(in_array($status, ['SYSTEM_CONFIG_VOID'])){$status = 'SYSTEM_CONFIG_VOID';}
else{$status = 'ETC';};
}else{
$status = NULL;
};
return $status;
}
private function getTotal($datas)
{
$total = [];
$total['impressions'] = 0;
$total['click'] = 0;
$total['spend'] = 0;
$total['margin'] = 0;
$total['unique_total'] = 0;
$total['sales'] = 0;
$total['budget'] = 0;
$total['bidamount'] = 0;
$total['cpc'] = 0;
$total['ctr'] = 0;
$total['cpa'] = 0;
$total['cvr'] = 0;
$total['margin_ratio'] = 0;
$total['expect_db'] = 0;
$total['avg_cpc'] = 0;
$total['avg_cpa'] = 0;
$total['avg_cvr'] = 0;
$total['avg_ctr'] = 0;
foreach($datas as $data){
$total['impressions'] +=$data['impressions'];
$total['click'] +=$data['click'];
$total['spend'] +=$data['spend'];
$total['margin'] +=$data['margin'];
$total['unique_total'] +=$data['unique_total'];
$total['sales'] +=$data['sales'];
$total['bidamount'] +=$data['bidamount'];
$total['budget'] +=$data['budget'];
$total['cpc'] +=$data['cpc'];
$total['ctr'] +=$data['ctr'];
$total['cpa'] +=$data['cpa'];
$total['cvr'] +=$data['cvr'];
$total['margin_ratio'] +=$data['margin_ratio'];
//CPC(Cost Per Click: 클릭당단가 (1회 클릭당 비용)) = 지출액/링크클릭
if($total['click'] > 0){
$total['avg_cpc'] = $total['spend'] / $total['click'];
}
//CTR(Click Through Rate: 클릭율 (노출 대비 클릭한 비율)) = (링크클릭/노출수)*100
if($total['impressions'] > 0){
$total['avg_ctr'] = ($total['click'] / $total['impressions']) * 100;
}
//CPA(Cost Per Action: 현재 DB단가(전환당 비용)) = 지출액/유효db
if($total['unique_total'] > 0){
$total['avg_cpa'] = $total['spend'] / $total['unique_total'];
}
//CVR(Conversion Rate:전환율 = (유효db / 링크클릭)*100
if ($total['click'] > 0) {
$total['avg_cvr'] = ($total['unique_total'] / $total['click']) * 100;
}
//수익률 = (수익/매출액)*100
if ($total['sales'] > 0) {
$total['avg_margin_ratio'] = ($total['margin'] / $total['sales']) * 100;
} else {
$total['avg_margin_ratio'] = 0;
}
if ($data['status'] == 'ON' && $data['unique_total'] && $data['cpa'] != 0){
$total['expect_db'] += round($data['budget'] / $data['cpa']);
}
}
$total['impressions'] = number_format($total['impressions']);
$total['bidamount'] = number_format($total['bidamount']);
$total['budget'] = number_format($total['budget']);
$total['click'] = number_format($total['click']);
$total['spend'] = number_format($total['spend']);
$total['avg_cpa'] = number_format($total['avg_cpa']);
$total['margin'] = number_format($total['margin']);
$total['sales'] = number_format($total['sales']);
$total['avg_cpc'] = number_format($total['avg_cpc']);
return $total;
}
}