Commit 2d493762 by Vladislav

#22112 Добавить команду и запрос остановки показа объявлений

1 parent b863e82a
......@@ -23,7 +23,7 @@ class AdvertisementsDelete extends Command
*
* @var string
*/
protected $description = 'Удаление созданных объявлени';
protected $description = 'Удаление созданных объявлений';
/**
* Create a new command instance.
......
<?php
namespace App\Console\Commands;
use App\Models\Pivots\GoalAdvertisement;
use App\Models\Tokens;
use App\Service\Requests\Direct\SuspendAds;
use Carbon\Carbon;
use Illuminate\Console\Command;
class AdvertisementsSuspend extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ads:suspend';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Остановить показы объявлений с целевого аккаунта';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$tokens = Tokens::has('dictionaryCampaignsEnabledForExternalSynchronized.goalAdvertisementsForNeedSuspendedForNotReserveSuspendForNotSuspended')
->where('type', '!=', Tokens::MAIN)
->get();
foreach ($tokens as $token) {
$this->sendRequest($token, $token->dictionaryCampaignsEnabledForExternalSynchronized->pluck('goalAdvertisementsForNeedSuspendedForNotReserveSuspendForNotSuspended')->collapse());
}
return 0;
}
private function sendRequest($token, $ads)
{
/* @var $ads GoalAdvertisement[] */
if (!$ads->count()) {
return;
}
foreach (array_chunk($ads->pluck('external_id')->toArray(), 100) as $items) {
GoalAdvertisement::whereIn('external_id', $items)
->update([
'reserve_suspend_at' => Carbon::now(),
]);
}
$request = new SuspendAds();
$request->setToken($token)
->call([
'ids' => $ads->pluck('external_id')->toArray(),
]);
}
}
......@@ -377,6 +377,26 @@ class DictionaryCampaignsSyncByCampaign extends Command
$this->info('update goal_advertisements.dictionary_campaign_external_id successful!');
DB::update("
UPDATE goal_advertisements ga
INNER JOIN goal_sitelinks gs on ga.goal_sitelink_id = gs.id AND gs.external_id is not null AND gs.updated_need is null AND gs.deleted_at is null
SET ga.goal_sitelink_external_id = gs.external_id,
ga.updated_at = CURRENT_TIMESTAMP
WHERE ga.deleted_at IS NULL
AND ga.goal_sitelink_external_id IS NULL
");
$this->info('update goal_advertisements.goal_sitelink_external_id successful!');
DB::update("
UPDATE goal_advertisements ga
LEFT JOIN goal_v_cards gvc on ga.goal_v_card_id = gvc.id AND gvc.external_id is not null AND gvc.deleted_at is null
SET ga.goal_v_card_external_id = gvc.external_id,
ga.updated_at = CURRENT_TIMESTAMP
WHERE ga.deleted_at IS NULL
AND ga.goal_v_card_external_id IS NULL
");
$this->info('update goal_advertisements.goal_v_card_external_id successful!');
DB::update("
UPDATE goal_bid_modifiers gbm
INNER JOIN dictionary_campaigns dc ON dc.id = gbm.dictionary_campaign_id AND dc.external_id IS NOT NULL AND dc.deleted_at IS NULL
SET gbm.dictionary_campaign_external_id = dc.external_id,
......
......@@ -5,7 +5,6 @@ namespace App\Console\Commands;
use App\Models\VCard;
use App\Models\Pivots\GoalVCard;
use App\Models\Tokens;
use App\Service\Requests\Direct\DeleteAds;
use App\Service\Requests\Direct\DeleteVCards;
use Carbon\Carbon;
use Illuminate\Console\Command;
......
......@@ -14,6 +14,7 @@ use App\Console\Commands\AdvertisementsAdd;
use App\Console\Commands\AdvertisementsArchive;
use App\Console\Commands\AdvertisementsDelete;
use App\Console\Commands\AdvertisementsLoadUpdated;
use App\Console\Commands\AdvertisementsSuspend;
use App\Console\Commands\AdvertisementsUpdate;
use App\Console\Commands\AudienceTargetsAdd;
use App\Console\Commands\AudienceTargetsDelete;
......@@ -144,6 +145,7 @@ class Kernel extends ConsoleKernel
$schedule->command(KeywordsAdd::class)->hourlyAt(40);
$schedule->command(KeywordsUpdate::class)->hourlyAt(40);
$schedule->command(AdvertisementsSuspend::class)->hourlyAt(40);
$schedule->command(AdvertisementsAdd::class)->hourlyAt(50);
$schedule->command(AdvertisementsUpdate::class)->hourlyAt(50);
$schedule->command(AdvertisementsArchive::class)->hourlyAt(50);
......
......@@ -515,6 +515,11 @@ class DictionaryCampaign extends Pivot
return $this->goalAdvertisements()->forExternal()->needArchived()->forNotReserveArchive()->forNotArchived();
}
public function goalAdvertisementsForNeedSuspendedForNotReserveSuspendForNotSuspended()
{
return $this->goalAdvertisements()->forExternal()->needSuspended()->forNotReserveSuspend()->forNotSuspended();
}
public function goalAdvertisementsForNeedDeletedForNotReserveDelete()
{
return $this->goalAdvertisements()->forExternal()->needDeleted()->forNotReserveDelete();
......
......@@ -81,6 +81,9 @@ class GoalAdvertisement extends Pivot
'reserve_archive_at',
'deleted_need',
'reserve_delete_at',
'suspended_need',
'suspended_at',
'reserve_suspend_at',
];
protected $casts = [
......@@ -94,6 +97,9 @@ class GoalAdvertisement extends Pivot
'reserve_archive_at' => 'datetime',
'deleted_need' => 'datetime',
'reserve_delete_at' => 'datetime',
'suspended_need' => 'datetime',
'suspended_at' => 'datetime',
'reserve_suspend_at' => 'datetime',
];
public $incrementing = true;
......@@ -195,7 +201,14 @@ class GoalAdvertisement extends Pivot
*/
public function scopeNeedArchived($query)
{
return $query->whereNotNull('archived_need');
return $query->whereNotNull('archived_need')
->where(function (Builder $query) {
return $query->whereNull('suspended_need')
->orWhere(function (Builder $query) {
return $query->whereNotNull('suspended_need')
->whereNotNull('suspended_at');
});
});
}
/**
......@@ -220,31 +233,59 @@ class GoalAdvertisement extends Pivot
* @param Builder $query
* @return Builder
*/
public function scopeNeedSuspended($query)
{
return $query->whereNotNull('suspended_need');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeForNotReserveSuspend($query)
{
return $query->whereNull('reserve_suspend_at');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeForNotSuspended($query)
{
return $query->whereNull('suspended_at');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeNeedDeleted($query)
{
return $query->whereNull('goal_advertisements.deleted_at')
->whereNull('goal_advertisements.archive_at')
->whereNull('goal_advertisements.archived_need')
->whereNull('goal_advertisements.suspended_need')
->where(function (Builder $query) {
return $query->whereNotNull('deleted_need')
->orWhere(function (Builder $query) {
return $query->whereExists(function (\Illuminate\Database\Query\Builder $query) {
$query->select(DB::raw(1))->from('advertisements')
->whereNotNull('advertisements.deleted_at')
->whereColumn('goal_advertisements.advertisement_id', 'advertisements.id');
});
})->orWhere(function (Builder $query) {
return $query->whereExists(function (\Illuminate\Database\Query\Builder $query) {
$query->select(DB::raw(1))
->from('goal_ad_groups')
->join('ad_groups', 'goal_ad_groups.ad_group_id', '=', 'ad_groups.id')
->whereNull('goal_ad_groups.deleted_at')
->whereNotNull('goal_ad_groups.external_id')
->whereNotNull('ad_groups.deleted_at')
->whereColumn('goal_advertisements.goal_ad_group_id', 'goal_ad_groups.id');
return $query->whereNotNull('deleted_need')
->orWhere(function (Builder $query) {
return $query->whereExists(function (\Illuminate\Database\Query\Builder $query) {
$query->select(DB::raw(1))->from('advertisements')
->whereNotNull('advertisements.deleted_at')
->whereColumn('goal_advertisements.advertisement_id', 'advertisements.id');
});
})->orWhere(function (Builder $query) {
return $query->whereExists(function (\Illuminate\Database\Query\Builder $query) {
$query->select(DB::raw(1))
->from('goal_ad_groups')
->join('ad_groups', 'goal_ad_groups.ad_group_id', '=', 'ad_groups.id')
->whereNull('goal_ad_groups.deleted_at')
->whereNotNull('goal_ad_groups.external_id')
->whereNotNull('ad_groups.deleted_at')
->whereColumn('goal_advertisements.goal_ad_group_id', 'goal_ad_groups.id');
});
});
});
});
});
}
/**
......
......@@ -78,7 +78,15 @@ class ArchiveAds extends DirectRequest
* ),
* )
*/
if (isset($archive_result['Errors'][0]['Code']) == 8300) {
if (
isset($archive_result['Errors'][0]['Code'])
&&
$archive_result['Errors'][0]['Code'] == 8300
&&
isset($add_result['Errors'][0]['Details'])
&&
$archive_result['Errors'][0]['Details'] === 'Ad is a draft and cannot be archived'
) {
if ($this->getToken()->isMain()) {
Advertisement::whereExternalId($external_id)
->update([
......@@ -94,6 +102,19 @@ class ArchiveAds extends DirectRequest
'reserve_archive_at' => null,
]);
}
} elseif (
isset($archive_result['Errors'][0]['Code'])
&&
$archive_result['Errors'][0]['Code'] == 8300
&&
isset($add_result['Errors'][0]['Details'])
&&
$archive_result['Errors'][0]['Details'] === 'Ad is currently being displayed and cannot be achieved direct'
) {
GoalAdvertisement::whereExternalId($external_id)
->update([
'suspended_need' => Carbon::now(),
]);
} elseif (isset($archive_result['Errors']) && count($archive_result['Errors'])) {
if ($this->getToken()->isMain()) {
$model = Advertisement::whereExternalId($external_id)->first();
......
<?php
namespace App\Service\Requests\Direct;
use App\Jobs\ProcessCallLimitedAPI;
use App\Models\Pivots\GoalAdvertisement;
use App\Service\Contract\APIRequest;
use App\Service\DirectResponseHelper;
use App\Service\Requests\DirectRequest;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class SuspendAds extends DirectRequest
{
protected $max_count = 10000;
protected $timestamp;
public function call($params = null)
{
$this->requestPrepare($params);
$process = new ProcessCallLimitedAPI($this);
dispatch($process)->onQueue('limits');
}
public function getObjectsCount()
{
return count($this->getParams()['SelectionCriteria']['Ids']);
}
public function slice($maxObjects): ?APIRequest
{
return $this->sliceByKey($maxObjects, ['SelectionCriteria', 'Ids']);;
}
public function handle($response)
{
if (!isset($response['result']['SuspendResults'])) {
return;
}
foreach (DirectResponseHelper::getExternalIdsChunkByResult($response['result']['SuspendResults']) as $external_ids) {
GoalAdvertisement::whereIn('external_id', $external_ids)
->update([
'suspended_at' => Carbon::now(),
'reserve_suspend_at' => null,
]);
}
foreach ($response['result']['SuspendResults'] as $key => $suspend_result) {
if (isset($suspend_result['Id'])) {
continue;
}
$external_id = $this->getParams()['SelectionCriteria']['Ids'][$key];
if (isset($suspend_result['Errors']) && count($suspend_result['Errors'])) {
$model = GoalAdvertisement::whereExternalId($external_id)->first();
if ($model) {
$model->errors()->create([
'token_id' => $this->getToken()->getKey(),
'service' => $this->getService(),
'method' => $this->getMethod(),
'params' => $external_id,
'errors' => $suspend_result['Errors'],
]);
}
} else {
Log::debug("SuspendAds, empty Id, token_id {$this->getToken()->getKey()}");
Log::debug($suspend_result);
Log::debug($external_id);
}
GoalAdvertisement::whereExternalId($external_id)
->update([
'reserve_suspend_at' => null,
]);
}
}
public function failed()
{
foreach (array_chunk($this->getParams()['SelectionCriteria']['Ids'], 100) as $items) {
GoalAdvertisement::whereIn('external_id', $items)
->update([
'reserve_suspend_at' => null,
]);
}
}
private function requestPrepare($params)
{
$this->setService('Ads');
$this->setMethod('suspend');
$this->setParams([
'SelectionCriteria' => [
'Ids' => $params['ids'],
],
]);
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddGoalAdvertisementsSuspendColumn extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('goal_advertisements', function (Blueprint $table) {
$table->timestamp('suspended_need')->nullable();
$table->timestamp('suspended_at')->nullable();
$table->timestamp('reserve_suspend_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!