Commit 36ce0046 by Vladislav

#19498 Снхронизация объявлений с целевыми

1 parent 86f47903
<?php
namespace App\Console\Commands;
use App\Models\Tokens;
use App\Service\API\API;
use App\Service\Requests\APIRequest;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Relations\HasMany;
class AdvertisementsAdd extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ads:add';
/**
* 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::whereHas('dictionaryCampaignsEnabledForExternalSynchronized.goalAdvertisementsForNotExternal.advertisement')
->where('type', '!=', Tokens::MAIN)
->get();
foreach ($tokens as $token) {
$token->load([
'dictionaryCampaignsEnabledForExternalSynchronized.goalAdvertisementsForNotExternal' => function (HasMany $query) {
return $query->has('advertisement');
},
'dictionaryCampaignsEnabledForExternalSynchronized.goalAdvertisementsForNotExternal.advertisement',
]);
$factory = APIRequest::getInstance(API::YANDEX);
$factory->setToken($token);
$factory->getRequest('Ads', 'add')
->call([
'goalAds' => $token->dictionaryCampaignsEnabledForExternalSynchronized->pluck('goalAdvertisementsForNotExternal')
->collapse(),
]);
}
return 0;
}
}
......@@ -17,7 +17,7 @@ class AdvertisementsLoadUpdated extends Command
*
* @var string
*/
protected $signature = 'ad:loadUpdated';
protected $signature = 'ads:loadUpdated';
/**
* The console command description.
......
......@@ -132,6 +132,18 @@ class DictionaryCampaignsSyncByCampaign extends Command
WHERE gk.keyword_id is null
");
//грузим ключевые фразы которых по какой то причне нет в целевых.
DB::insert("
INSERT INTO goal_advertisements(dictionary_campaign_external_id, goal_ad_group_external_id, dictionary_campaign_id,
goal_ad_group_id, advertisement_id)
SELECT gag.dictionary_campaign_id, gag.external_id, gag.dictionary_campaign_id, gag.id, ad.id
FROM advertisements ad
INNER JOIN ad_groups ag on ad.ad_group_id = ag.id
INNER JOIN goal_ad_groups gag on ag.id = gag.ad_group_id
LEFT JOIN goal_advertisements gad on ad.id = gad.advertisement_id AND gad.goal_ad_group_id=gag.id
WHERE gad.advertisement_id is null
");
DictionaryCampaign::needSynced()->update([
'synced_need' => null,
]);
......
......@@ -433,4 +433,19 @@ class DictionaryCampaign extends Pivot
return $this->hasMany(GoalKeywordDelete::class, 'dictionary_campaign_id');
}
public function goalAdvertisements()
{
return $this->hasMany(GoalAdvertisement::class, 'dictionary_campaign_id');
}
public function goalAdvertisementsForNotExternal()
{
return $this->goalAdvertisements()->forNotExternal();
}
public function goalAdvertisementsForNeedUpdated()
{
return $this->goalAdvertisements()->needUpdated();
}
}
......@@ -197,4 +197,9 @@ class GoalAdGroup extends Pivot
return $this->hasMany(GoalKeyword::class, 'goal_ad_group_id');
}
public function goalAdvertisements()
{
return $this->hasMany(GoalAdvertisement::class, 'goal_ad_group_id');
}
}
<?php
namespace App\Models\Pivots;
use App\Models\Advertisement;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* App\Models\Pivots\GoalAdvertisement
*
* @property int $id
* @property int|null $external_id
* @property int|null $dictionary_campaign_external_id
* @property int|null $goal_ad_group_external_id
* @property int $dictionary_campaign_id
* @property int $goal_ad_group_id
* @property int $advertisement_id
* @property \Illuminate\Support\Carbon|null $external_upload_at
* @property \Illuminate\Support\Carbon|null $external_updated_at
* @property \Illuminate\Support\Carbon|null $updated_need
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read Advertisement $advertisement
* @method static Builder|GoalAdvertisement forExternal()
* @method static Builder|GoalAdvertisement forNotExternal()
* @method static Builder|GoalAdvertisement needUpdated()
* @method static Builder|GoalAdvertisement newModelQuery()
* @method static Builder|GoalAdvertisement newQuery()
* @method static Builder|GoalAdvertisement query()
* @method static Builder|GoalAdvertisement whereCreatedAt($value)
* @method static Builder|GoalAdvertisement whereDictionaryCampaignExternalId($value)
* @method static Builder|GoalAdvertisement whereDictionaryCampaignId($value)
* @method static Builder|GoalAdvertisement whereExternalId($value)
* @method static Builder|GoalAdvertisement whereExternalUpdatedAt($value)
* @method static Builder|GoalAdvertisement whereExternalUploadAt($value)
* @method static Builder|GoalAdvertisement whereGoalAdGroupExternalId($value)
* @method static Builder|GoalAdvertisement whereGoalAdGroupId($value)
* @method static Builder|GoalAdvertisement whereId($value)
* @method static Builder|GoalAdvertisement whereAdvertisementId($value)
* @method static Builder|GoalAdvertisement whereUpdatedAt($value)
* @method static Builder|GoalAdvertisement whereUpdatedNeed($value)
* @mixin \Eloquent
*/
class GoalAdvertisement extends Pivot
{
use SoftDeletes;
protected $table = 'goal_advertisements';
protected $fillable = [
'external_id',
'goal_ad_group_external_id',
'dictionary_campaign_external_id',
'goal_ad_group_id',
'dictionary_campaign_id',
'advertisement_id',
'external_upload_at',
'external_updated_at',
'updated_need',
'reserve_create_at',
];
protected $casts = [
'external_upload_at' => 'datetime',
'external_updated_at' => 'datetime',
'updated_need' => 'datetime',
'reserve_create_at' => 'datetime',
];
public $incrementing = true;
static public function getWithPivot()
{
return [
'id',
'external_id',
'goal_ad_group_external_id',
'dictionary_campaign_external_id',
'goal_ad_group_id',
'dictionary_campaign_id',
'advertisement_id',
'external_upload_at',
'external_updated_at',
'updated_need',
];
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeForExternal($query)
{
return $query->whereNotNull('external_id');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeForNotExternal($query)
{
return $query->whereNull('external_id');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeNeedUpdated($query)
{
return $query->whereNotNull('updated_need');
}
public function advertisement()
{
return $this->belongsTo(Advertisement::class, 'advertisement_id');
}
public function dictionaryCampaign()
{
return $this->belongsTo(DictionaryCampaign::class, 'dictionary_campaign_id');
}
}
......@@ -3,8 +3,6 @@
namespace App\Service\Requests\Direct;
use App\Jobs\ProcessCallLimitedAPI;
use App\Models\Campaigns;
use App\Models\Pivots\DictionaryCampaign;
use App\Models\Pivots\GoalAdGroup;
use App\Models\Variable;
use App\Service\Contract\APIRequest;
......@@ -82,6 +80,10 @@ class AddAdGroups extends DirectRequest
'goal_ad_group_external_id' => $external_id,
]);
$goalAdGroup->goalAdvertisements()->update([
'goal_ad_group_external_id' => $external_id,
]);
}
} catch (\Exception $e) {
Log::debug($e);
......
<?php
namespace App\Service\Requests\Direct;
use App\Jobs\ProcessCallLimitedAPI;
use App\Models\Pivots\GoalAdGroup;
use App\Models\Pivots\GoalAdvertisement;
use App\Models\Variable;
use App\Service\Contract\APIRequest;
use App\Service\Requests\DirectRequest;
use App\Service\StrReplaceByVariables;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Log;
class AddAds extends DirectRequest
{
protected $max_count = 1000;
protected $timestamp;
/* @var Collection|GoalAdvertisement[] */
protected $goalAds;
public function call($params = null)
{
$this->requestPrepare($params);
$process = new ProcessCallLimitedAPI($this);
dispatch($process)->onQueue('limits');
}
public function getObjectsCount()
{
return count($this->getParams()['Ads']);
}
public function slice($maxObjects): ?APIRequest
{
$splinter = $this->sliceByKey($maxObjects, 'Ads');
$splinter->putParams([
'goalAds' => $this->goalAds->slice($maxObjects)->values(),
]);
$this->putParams([
'goalAds' => $this->goalAds->slice(0, $maxObjects),
]);
return $splinter;
}
public function handle($response)
{
try {
if (isset($response['result']['Errors'])) {
Log::debug($response['Errors']);
Log::debug($this->getParams());
}
if (!isset($response['result']['AddResults'])) {
return;
}
foreach ($response['result']['AddResults'] as $key => $add_result) {
if (!isset($add_result['Id'])) {
Log::debug("AddAds, empty Id");
Log::debug($add_result);
Log::debug($this->getParams());
continue;
}
$external_id = (string)$add_result['Id'];
$goalAd = $this->goalAds->get($key);
$goalAd->update([
'external_id' => $external_id,
'external_upload_at' => Carbon::now(),
]);
}
} catch (\Exception $e) {
Log::debug($e);
throw $e;
}
}
public function putParams($params)
{
$this->goalAds = $params['goalAds'];
}
private function requestPrepare($params)
{
$this->setService('Ads');
$this->setMethod('add');
$this->putParams($params);
$variables = Variable::all();
$lists = [];
$this->setParams([
'Ads' => $this->goalAds->map(function (GoalAdvertisement $goalAdvertisement) use ($variables, &$lists) {
if (!isset($lists[$goalAdvertisement->dictionary_campaign_id])) {
$list = Variable::getListVariablesByDictionaryCampaign($goalAdvertisement->dictionary_campaign_id, $variables);
$lists[$goalAdvertisement->dictionary_campaign_id] = $list;
} else {
$list = $lists[$goalAdvertisement->dictionary_campaign_id];
}
$advertisement = $goalAdvertisement->advertisement;
$data = [
'AdGroupId' => $goalAdvertisement->goal_ad_group_external_id,
'TextAd' => [
'Title' => StrReplaceByVariables::getInstance($advertisement->title, $list)->get(),
'Text' => StrReplaceByVariables::getInstance($advertisement->text, $list)->get(),
'Mobile' => $advertisement->mobile ? 'YES' : 'NO',
],
];
if ($advertisement->title2) {
$data['TextAd']['Title2'] = StrReplaceByVariables::getInstance($advertisement->title2, $list)->get();
}
if ($advertisement->href) {
$data['TextAd']['Href'] = $advertisement->href;
}
if ($advertisement->display_url_path) {
$data['TextAd']['DisplayUrlPath'] = $advertisement->display_url_path;
}
if ($advertisement->v_card_id) {
$data['TextAd']['VCardId'] = $advertisement->v_card_id;
}
if ($advertisement->ad_image_hash) {
$data['TextAd']['AdImageHash'] = $advertisement->ad_image_hash;
}
if ($advertisement->site_link_set_id) {
$data['TextAd']['SitelinkSetId'] = $advertisement->site_link_set_id;
}
if ($advertisement->ad_extensions) {
$data['TextAd']['AdExtensionIds'] = array_map(function ($ad_extension) { return $ad_extension['AdExtensionId']; }, $advertisement->ad_extensions);
}
if ($advertisement->video_extension) {
$data['TextAd']['VideoExtension'] = [
'CreativeId' => $advertisement->video_extension['CreativeId'],
];
}
if ($advertisement->price_extension) {
$data['TextAd']['PriceExtension'] = [
'Price' => $advertisement->price_extension['Price'],
'PriceQualifier' => $advertisement->price_extension['PriceQualifier'],
'PriceCurrency' => $advertisement->price_extension['PriceCurrency'],
];
if (isset($advertisement->price_extension['OldPrice']) && !is_null($advertisement->price_extension['OldPrice'])) {
$data['TextAd']['PriceExtension']['OldPrice'] = $advertisement->price_extension['OldPrice'];
}
}
if ($advertisement->turbo_page_id) {
$data['TextAd']['TurboPageId'] = $advertisement->turbo_page_id;
}
if ($advertisement->business_id) {
$data['TextAd']['BusinessId'] = $advertisement->business_id;
}
if ($advertisement->prefer_v_card_over_business) {
$data['TextAd']['PreferVCardOverBusiness'] = $advertisement->prefer_v_card_over_business ? 'YES' : 'NO';
}
return $data;
})->toArray(),
]);
}
}
......@@ -86,6 +86,10 @@ class AddCampaigns extends DirectRequest
'dictionary_campaign_external_id' => $external_id,
]);
$dictionaryCampaign->goalAdvertisements()->update([
'dictionary_campaign_external_id' => $external_id,
]);
}
} catch (\Exception $e) {
Log::debug($e);
......
......@@ -131,7 +131,7 @@ class GetAds extends DirectRequest
'turbo_page_id' => $ad['TextAd']['TurboPageId'],
'turbo_page_moderation' => $ad['TextAd']['TurboPageModeration'],
'business_id' => $ad['TextAd']['BusinessId'],
'prefer_v_card_over_business' => $ad['TextAd']['PreferVCardOverBusiness'],
'prefer_v_card_over_business' => $ad['TextAd']['PreferVCardOverBusiness'] === 'YES',
]);
}
......
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGoalAdvertisementsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('goal_advertisements', function (Blueprint $table) {
$table->id();
$table->bigInteger('external_id')->nullable();
$table->bigInteger('dictionary_campaign_external_id')->nullable();
$table->bigInteger('goal_ad_group_external_id')->nullable();
$table->bigInteger('dictionary_campaign_id')->unsigned();
$table->bigInteger('goal_ad_group_id')->unsigned();
$table->bigInteger('advertisement_id')->unsigned();
$table->timestamp('external_upload_at')->nullable();
$table->timestamp('external_updated_at')->nullable();
$table->timestamp('updated_need')->nullable();
$table->softDeletes();
$table->timestamps();
$table->foreign('dictionary_campaign_id')->references('id')->on('dictionary_campaigns')
->cascadeOnDelete();
$table->foreign('goal_ad_group_id')->references('id')->on('goal_ad_groups')
->cascadeOnDelete();
$table->foreign('advertisement_id')->references('id')->on('advertisements')
->cascadeOnDelete();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('goal_advertisements');
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!