Commit 803b9111 by Vladislav

#20414 Загрузка и синхронизация VCards

1 parent 50296486
...@@ -120,6 +120,17 @@ class DictionaryCampaignsSyncByCampaign extends Command ...@@ -120,6 +120,17 @@ class DictionaryCampaignsSyncByCampaign extends Command
WHERE gnkss.id is null and nkss.deleted_at is null WHERE gnkss.id is null and nkss.deleted_at is null
"); ");
//грузим виртуальные визитки которых по какой то причне нет в целевых.
DB::insert("
INSERT INTO goal_v_cards(ad_group_id, dictionary_campaign_external_id, dictionary_campaign_id, name, negative_keywords, created_at, updated_at)
SELECT a.id, dc.external_id, dc.id, a.name, a.negative_keywords, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
FROM v_cards vc
INNER JOIN campaigns c on vc.campaign_id = c.id
INNER JOIN dictionary_campaigns dc on c.id = dc.campaign_id
LEFT JOIN goal_v_cards gvc on a.id = gag.ad_group_id AND gag.dictionary_campaign_id=dc.id
WHERE gag.ad_group_id is null
");
//грузим группы которых по какой то причне нет в целевых. //грузим группы которых по какой то причне нет в целевых.
DB::insert(" DB::insert("
INSERT INTO goal_ad_groups(ad_group_id, dictionary_campaign_external_id, dictionary_campaign_id, name, negative_keywords, created_at, updated_at) INSERT INTO goal_ad_groups(ad_group_id, dictionary_campaign_external_id, dictionary_campaign_id, name, negative_keywords, created_at, updated_at)
......
<?php
namespace App\Console\Commands;
use App\Models\Pivots\GoalAdExtension;
use App\Models\Pivots\GoalNegativeKeywordSharedSet;
use App\Models\Pivots\GoalVCard;
use App\Models\Tokens;
use App\Service\API\API;
use App\Service\Requests\APIRequest;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Relations\HasMany;
class VCardsAdd extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'vcards: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
* @throws \Exception
*/
public function handle()
{
$tokens = Tokens::whereHas('dictionaryCampaignsEnabledForExternalSynchronized.goalVCardsForNotExternalForNotReserveCreate.vCard')
->where('type', '!=', Tokens::MAIN)
->get();
foreach ($tokens as $token) {
$token->load([
'dictionaryCampaignsEnabledForExternalSynchronized.goalVCardsForNotExternalForNotReserveCreate' => function (HasMany $query) {
return $query->has('vCard');
},
'dictionaryCampaignsEnabledForExternalSynchronized.goalVCardsForNotExternalForNotReserveCreate.vCard',
]);
$factory = APIRequest::getInstance(API::YANDEX);
$factory->setToken($token);
$goalVCards = $token->dictionaryCampaignsEnabledForExternalSynchronized->pluck('goalVCardsForNotExternalForNotReserveCreate')
->collapse();
foreach (array_chunk($goalVCards->pluck('id')->toArray(), 1000) as $items) {
GoalVCard::whereIn('id', $items)
->update([
'reserve_create_at' => Carbon::now(),
]);
}
$factory->getRequest('VCards', 'add')
->call([
'goalVCards' => $goalVCards,
]);
}
return 0;
}
}
<?php
namespace App\Console\Commands;
use App\Models\Campaigns;
use App\Models\Tokens;
use App\Service\API\API;
use App\Service\Requests\APIRequest;
use Illuminate\Console\Command;
class VCardsLoad extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'vcards:load';
/**
* 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
* @throws \Exception
*/
public function handle()
{
$token = Tokens::where('type', Tokens::MAIN)->first();
if (!$token) {
throw new \Exception('Не найден токен блин');
}
$factory = APIRequest::getInstance(API::YANDEX);
$factory->setToken($token);
$factory->getRequest('VCards', 'get')
->call();
return 0;
}
}
...@@ -36,7 +36,7 @@ class NegativeKeywordSharedSet extends Model ...@@ -36,7 +36,7 @@ class NegativeKeywordSharedSet extends Model
]); ]);
} }
public function goalNegativeKeywordSharedSet() public function goalNegativeKeywordSharedSets()
{ {
return $this->hasMany(GoalNegativeKeywordSharedSet::class, 'negative_keyword_shared_set_id'); return $this->hasMany(GoalNegativeKeywordSharedSet::class, 'negative_keyword_shared_set_id');
} }
......
...@@ -511,4 +511,14 @@ class DictionaryCampaign extends Pivot ...@@ -511,4 +511,14 @@ class DictionaryCampaign extends Pivot
return $this->goalAdvertisements()->forNotExternal(); return $this->goalAdvertisements()->forNotExternal();
} }
public function goalVCards()
{
return $this->hasMany(GoalVCard::class, 'dictionary_campaign_id');
}
public function goalVCardsForNotExternalForNotReserveCreate()
{
return $this->goalVCards()->forNotExternal()->forNotReserveCreate();
}
} }
<?php
namespace App\Models\Pivots;
use App\Models\AdExtension;
use App\Models\NegativeKeywordSharedSet;
use App\Models\VCard;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\SoftDeletes;
class GoalVCard extends Pivot
{
use SoftDeletes;
protected $table = 'goal_v_card';
protected $fillable = [
'external_id',
'dictionary_campaign_external_id',
'v_card_id',
'dictionary_campaign_id',
'external_upload_at',
'external_updated_at',
'updated_need',
'reserve_create_at',
'reserve_update_at',
];
protected $casts = [
'external_upload_at' => 'datetime',
'external_updated_at' => 'datetime',
'updated_need' => 'datetime',
'reserve_create_at' => 'datetime',
'reserve_update_at' => 'datetime',
];
public $incrementing = true;
static public function getWithPivot()
{
return [
'id',
'external_id',
'dictionary_campaign_external_id',
'v_card_id',
'dictionary_campaign_id',
'external_upload_at',
'external_updated_at',
'updated_need',
'reserve_create_at',
'reserve_update_at',
];
}
/**
* @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 scopeForNotReserveCreate($query)
{
return $query->whereNull('reserve_create_at');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeForNotReserveUpdate($query)
{
return $query->whereNull('reserve_update_at');
}
/**
* @param Builder $query
* @return Builder
*/
public function scopeNeedUpdated($query)
{
return $query->whereNotNull('updated_need');
}
public function vCard()
{
return $this->belongsTo(VCard::class, 'v_card_id');
}
public function dictionaryCampaign()
{
return $this->belongsTo(DictionaryCampaign::class, 'dictionary_campaign_id');
}
}
<?php
namespace App\Models;
use App\Models\Pivots\GoalNegativeKeywordSharedSet;
use App\Models\Pivots\GoalVCard;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
class VCard extends Model
{
use SoftDeletes;
protected $table = 'v_cards';
protected $fillable = [
'external_id',
'campaign_external_id',
'campaign_id',
'country',
'city',
'work_time',
'phone',
'street',
'house',
'building',
'apartment',
'instant_messenger',
'company_name',
'extra_message',
'contact_email',
'ogrn',
'metro_station_id',
'point_on_map',
'contact_person',
];
protected $casts = [
'phone' => 'json',
'instant_messenger' => 'json',
'point_on_map' => 'json',
];
/**
* @return Collection
*/
static public function getPropertiesWatch()
{
return collect([
'country',
'city',
'work_time',
'phone',
'street',
'house',
'building',
'apartment',
'instant_messenger',
'company_name',
'extra_message',
'contact_email',
'ogrn',
'metro_station_id',
'point_on_map',
'contact_person',
]);
}
public function goalVCards()
{
return $this->hasMany(GoalVCard::class, 'v_card_id');
}
}
...@@ -97,6 +97,10 @@ class AddCampaigns extends DirectRequest ...@@ -97,6 +97,10 @@ class AddCampaigns extends DirectRequest
'dictionary_campaign_external_id' => $external_id, 'dictionary_campaign_external_id' => $external_id,
]); ]);
$dictionaryCampaign->goalVCards()->update([
'dictionary_campaign_external_id' => $external_id,
]);
} }
} catch (\Exception $e) { } catch (\Exception $e) {
Log::debug($e); Log::debug($e);
......
<?php
namespace App\Service\Requests\Direct;
use App\Jobs\ProcessCallLimitedAPI;
use App\Models\NegativeKeywordSharedSet;
use App\Models\Pivots\GoalNegativeKeywordSharedSet;
use App\Models\Pivots\GoalVCard;
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 AddVCards extends DirectRequest
{
protected $max_count = 30;
protected $timestamp;
/* @var Collection|NegativeKeywordSharedSet[] */
protected $goalVCards;
public function call($params = null)
{
$this->requestPrepare($params);
$process = new ProcessCallLimitedAPI($this);
dispatch($process)->onQueue('limits');
}
public function getObjectsCount()
{
return count($this->getParams()['VCards']);
}
public function slice($maxObjects): ?APIRequest
{
$splinter = $this->sliceByKey($maxObjects, 'VCards');
$splinter->putParams([
'goalVCards' => $this->goalVCards->slice($maxObjects)->values(),
]);
$this->putParams([
'goalVCards' => $this->goalVCards->slice(0, $maxObjects),
]);
return $splinter;
}
public function handle($response)
{
try {
if (!isset($response['result']['AddResults'])) {
return;
}
foreach ($response['result']['AddResults'] as $key => $add_result) {
$goalVCard = $this->goalVCards->get($key);
if (!isset($add_result['Id'])) {
Log::debug("AddNegativeKeywordSharedSet, empty Id");
Log::debug($add_result);
Log::debug($this->getParams()['VCards'][$key]);
$goalVCard->update([
'reserve_create_at' => null,
]);
continue;
}
$external_id = (string)$add_result['Id'];
$goalVCard->update([
'external_id' => $external_id,
'external_upload_at' => Carbon::now(),
'reserve_create_at' => null,
]);
}
} catch (\Exception $e) {
Log::debug($e);
throw $e;
}
}
public function failed()
{
GoalVCard::whereIn('id', $this->goalVCards->pluck('id')->toArray())
->update([
'reserve_create_at' => null,
]);
}
public function putParams($params)
{
$this->goalVCards = $params['goalVCards'];
}
private function requestPrepare($params)
{
$this->setService('VCards');
$this->setMethod('add');
$this->putParams($params);
$variables = Variable::all();
$lists = [];
$this->setParams([
'VCards' => $this->goalVCards->map(function (GoalVCard $goalVCard) use ($variables, &$lists) {
if (!isset($lists[$goalVCard->dictionary_campaign_id])) {
$list = Variable::getListVariablesByDictionaryCampaign($goalVCard->dictionary_campaign_id, $variables);
$lists[$goalVCard->dictionary_campaign_id] = $list;
} else {
$list = $lists[$goalVCard->dictionary_campaign_id];
}
return [
'CampaignId' => $goalVCard->dictionary_campaign_external_id,
'Country' => StrReplaceByVariables::getInstance($goalVCard->vCard->country, $list)->get(),
'City' => StrReplaceByVariables::getInstance($goalVCard->vCard->city, $list)->get(),
'CompanyName' => StrReplaceByVariables::getInstance($goalVCard->vCard->company_name, $list)->get(),
'WorkTime' => StrReplaceByVariables::getInstance($goalVCard->vCard->work_time, $list)->get(),
'Phone' => array_map(function ($phone) use ($list) {
return StrReplaceByVariables::getInstance($phone, $list)->get();
}, $goalVCard->vCard->phone),
'Street' => StrReplaceByVariables::getInstance($goalVCard->vCard->street, $list)->get(),
'House' => StrReplaceByVariables::getInstance($goalVCard->vCard->house, $list)->get(),
'Building' => StrReplaceByVariables::getInstance($goalVCard->vCard->building, $list)->get(),
'Apartment' => StrReplaceByVariables::getInstance($goalVCard->vCard->apartment, $list)->get(),
'InstantMessenger' => array_map(function ($instant_messenger) use ($list) {
return StrReplaceByVariables::getInstance($instant_messenger, $list)->get();
}, $goalVCard->vCard->instant_messenger),
'ExtraMessage' => StrReplaceByVariables::getInstance($goalVCard->vCard->extra_message, $list)->get(),
'ContactEmail' => StrReplaceByVariables::getInstance($goalVCard->vCard->contact_email, $list)->get(),
'Ogrn' => StrReplaceByVariables::getInstance($goalVCard->vCard->ogrn, $list)->get(),
'MetroStationId' => StrReplaceByVariables::getInstance($goalVCard->vCard->metro_station_id, $list)->get(),
'PointOnMap' => array_map(function ($point_on_map) use ($list) {
return StrReplaceByVariables::getInstance($point_on_map, $list)->get();
}, $goalVCard->vCard->point_on_map),
'ContactPerson' => StrReplaceByVariables::getInstance($goalVCard->vCard->contact_person, $list)->get(),
];
})->toArray(),
]);
}
}
...@@ -66,7 +66,7 @@ class GetNegativeKeywordSharedSets extends DirectRequest ...@@ -66,7 +66,7 @@ class GetNegativeKeywordSharedSets extends DirectRequest
], $data); ], $data);
if ($adExtension->wasChanged($adExtension::getPropertiesWatch()->toArray())) { if ($adExtension->wasChanged($adExtension::getPropertiesWatch()->toArray())) {
$adExtension->goalNegativeKeywordSharedSet()->forExternal()->update([ $adExtension->goalNegativeKeywordSharedSets()->forExternal()->update([
'updated_need' => Carbon::now(), 'updated_need' => Carbon::now(),
]); ]);
} }
......
<?php
namespace App\Service\Requests\Direct;
use App\Jobs\ProcessCallLimitedAPI;
use App\Models\AdExtension;
use App\Models\AdGroup;
use App\Models\Advertisement;
use App\Models\Campaigns;
use App\Models\NegativeKeywordSharedSet;
use App\Models\VCard;
use App\Service\Contract\APIRequest;
use App\Service\Requests\DirectRequest;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class GetVCards extends DirectRequest
{
protected $max_count = -1;
protected $max_count_Ids = 10000;
function call($params = null)
{
$this->requestPrepare($params);
$process = new ProcessCallLimitedAPI($this);
dispatch($process)->onQueue('limits');
}
public function getObjectsCount()
{
$params = $this->getParams();
if (isset($params['SelectionCriteria']['Ids'])) {
return count($params['SelectionCriteria']['Ids']);
}
return -1;
}
public function slice($maxObjects): ?APIRequest
{
$params = $this->getParams();
if (isset($params['SelectionCriteria']['Ids'])) {
return $this->sliceByKey($maxObjects, ['SelectionCriteria', 'Ids']);
}
return null;
}
function handle($response)
{
try {
if (isset($response['result']['VCards'])) {
foreach ($response['result']['VCards'] as $v_card) {
$external_id = (string)$v_card['Id'];
$campaign_id_external_id = (string)$v_card['CampaignId'];
$campaign = Campaigns::firstWhere('external_id', $campaign_id_external_id);
if (!$campaign) {
continue;
}
if ($this->getToken()->isMain()) {
$data = [
'external_id' => $external_id,
'campaign_external_id' => $campaign->external_id,
'campaign_id' => $campaign->getKey(),
'country' => $v_card['Country'],
'city' => $v_card['City'],
'work_time' => $v_card['WorkTime'],
'phone' => $v_card['Phone'],
'street' => $v_card['Street'],
'house' => $v_card['House'],
'building' => $v_card['Building'],
'apartment' => $v_card['Apartment'],
'instant_messenger' => $v_card['InstantMessenger'],
'company_name' => $v_card['CompanyName'],
'extra_message' => $v_card['ExtraMessage'],
'contact_email' => $v_card['ContactEmail'],
'ogrn' => $v_card['Ogrn'],
'metro_station_id' => $v_card['MetroStationId'],
'point_on_map' => $v_card['PointOnMap'],
'contact_person' => $v_card['ContactPerson'],
];
$adExtension = VCard::updateOrCreate([
'external_id' => $external_id
], $data);
if ($adExtension->wasChanged($adExtension::getPropertiesWatch()->toArray())) {
$adExtension->goalVCards()->forExternal()->update([
'updated_need' => Carbon::now(),
]);
}
} else {
//
}
}
}
} catch (\Exception $e) {
Log::debug($e);
throw $e;
}
}
private function requestPrepare($filter)
{
$this->setService('VCards');
$this->setMethod('get');
$params = [
"FieldNames" => [
"Id", "CampaignId", "Country", "City",
"Street", "House", "Building", "Apartment",
"CompanyName", "ExtraMessage", "ContactPerson",
"ContactEmail", "MetroStationId", "Ogrn",
"WorkTime", "InstantMessenger", "Phone", "PointOnMap",
],
];
if (isset($filter['Ids'])) {
$this->max_count = $this->max_count_Ids;
$params['SelectionCriteria'] = [
'Ids' => $filter['Ids'],
];
}
$this->setParams($params);
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateVCardsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v_cards', function (Blueprint $table) {
$table->id();
$table->bigInteger('external_id');
$table->bigInteger('campaign_external_id');
$table->bigInteger('campaign_id')->unsigned();
$table->string('country')->nullable();
$table->string('city')->nullable();
$table->string('work_time')->nullable();
$table->json('phone')->nullable();
$table->string('street')->nullable();
$table->string('house')->nullable();
$table->string('building')->nullable();
$table->string('apartment')->nullable();
$table->json('instant_messenger')->nullable();
$table->string('company_name')->nullable();
$table->string('extra_message')->nullable();
$table->string('contact_email')->nullable();
$table->string('ogrn')->nullable();
$table->string('metro_station_id')->nullable();
$table->json('point_on_map')->nullable();
$table->string('contact_person')->nullable();
$table->foreign('campaign_id')->references('id')->on('campaigns')
->cascadeOnDelete();
$table->softDeletes();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v_cards');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGoalVCardsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('goal_v_cards', function (Blueprint $table) {
$table->id();
$table->bigInteger('external_id')->nullable();
$table->bigInteger('dictionary_campaign_external_id')->nullable();
$table->bigInteger('v_card_id')->unsigned();
$table->bigInteger('dictionary_campaign_id')->unsigned();
$table->timestamp('external_upload_at')->nullable();
$table->timestamp('external_updated_at')->nullable();
$table->timestamp('updated_need')->nullable();
$table->timestamp('reserve_create_at')->nullable();
$table->timestamp('reserve_update_at')->nullable();
$table->foreign('v_card_id')->references('id')->on('v_cards')
->cascadeOnDelete();
$table->foreign('dictionary_campaign_id')->references('id')->on('dictionary_campaigns')
->cascadeOnDelete();
$table->softDeletes();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('goal_v_cards');
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!