Add initial HTML template for MojeGS1 application with Cookiebot and Google Analytics integration
This commit is contained in:
140
src/Modules/Cron/ProductLinksHealthCheckHandler.php
Normal file
140
src/Modules/Cron/ProductLinksHealthCheckHandler.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Cron;
|
||||
|
||||
use App\Modules\ProductLinks\ChannelOffersRepository;
|
||||
use App\Modules\ProductLinks\OfferImportService;
|
||||
use App\Modules\ProductLinks\ProductLinksRepository;
|
||||
use App\Modules\Settings\IntegrationRepository;
|
||||
use Throwable;
|
||||
|
||||
final class ProductLinksHealthCheckHandler
|
||||
{
|
||||
private const ALERT_TYPE = 'missing_remote_link';
|
||||
private const ALERT_MESSAGE = 'Powiazanie nie istnieje juz po stronie zewnetrznej.';
|
||||
|
||||
public function __construct(
|
||||
private readonly IntegrationRepository $integrations,
|
||||
private readonly OfferImportService $offerImportService,
|
||||
private readonly ProductLinksRepository $links,
|
||||
private readonly ChannelOffersRepository $offers
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $payload
|
||||
* @param array<string, mixed> $job
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function __invoke(array $payload = [], array $job = []): array
|
||||
{
|
||||
$forcedIntegrationId = max(0, (int) ($payload['integration_id'] ?? 0));
|
||||
$activeIntegrations = array_values(array_filter(
|
||||
$this->integrations->listByType('shoppro'),
|
||||
static function (array $integration) use ($forcedIntegrationId): bool {
|
||||
$id = (int) ($integration['id'] ?? 0);
|
||||
if ($forcedIntegrationId > 0 && $id !== $forcedIntegrationId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $id > 0
|
||||
&& ($integration['is_active'] ?? false) === true
|
||||
&& ($integration['has_api_key'] ?? false) === true;
|
||||
}
|
||||
));
|
||||
|
||||
if ($activeIntegrations === []) {
|
||||
return [
|
||||
'ok' => true,
|
||||
'message' => 'Brak aktywnych integracji z kluczem API do weryfikacji powiazan.',
|
||||
'checked_links' => 0,
|
||||
'missing_links' => 0,
|
||||
'integrations' => 0,
|
||||
'integration_failures' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$checkedLinks = 0;
|
||||
$missingLinks = 0;
|
||||
$resolvedAlerts = 0;
|
||||
$integrationFailures = 0;
|
||||
$errors = [];
|
||||
$checkedAt = date('Y-m-d H:i:s');
|
||||
|
||||
foreach ($activeIntegrations as $integration) {
|
||||
$integrationId = (int) ($integration['id'] ?? 0);
|
||||
if ($integrationId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$credentials = $this->integrations->findApiCredentials($integrationId);
|
||||
} catch (Throwable $exception) {
|
||||
$integrationFailures++;
|
||||
if (count($errors) < 5) {
|
||||
$errors[] = 'Integracja #' . $integrationId . ': ' . $exception->getMessage();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($credentials === null || trim((string) ($credentials['api_key'] ?? '')) === '') {
|
||||
$integrationFailures++;
|
||||
if (count($errors) < 5) {
|
||||
$errors[] = 'Integracja #' . $integrationId . ': brak poprawnych danych API.';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$import = $this->offerImportService->importShopProOffers($credentials);
|
||||
if (($import['ok'] ?? false) !== true) {
|
||||
$integrationFailures++;
|
||||
if (count($errors) < 5) {
|
||||
$errors[] = 'Integracja #' . $integrationId . ': ' . trim((string) ($import['message'] ?? 'Blad importu ofert.'));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$links = $this->links->listActiveLinksForMissingCheck($integrationId);
|
||||
foreach ($links as $link) {
|
||||
$mapId = (int) ($link['id'] ?? 0);
|
||||
$externalProductId = trim((string) ($link['external_product_id'] ?? ''));
|
||||
$externalVariantId = $this->nullableText($link['external_variant_id'] ?? null);
|
||||
if ($mapId <= 0 || $externalProductId === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$checkedLinks++;
|
||||
$offer = $this->offers->findByExternalIdentity($integrationId, $externalProductId, $externalVariantId);
|
||||
|
||||
if ($offer === null) {
|
||||
$missingLinks++;
|
||||
$this->links->upsertActiveAlert($mapId, self::ALERT_TYPE, self::ALERT_MESSAGE, $checkedAt);
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->links->resolveActiveAlert($mapId, self::ALERT_TYPE, $checkedAt);
|
||||
$resolvedAlerts++;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'ok' => $integrationFailures === 0,
|
||||
'message' => $integrationFailures === 0
|
||||
? 'Weryfikacja powiazan zakonczona.'
|
||||
: 'Weryfikacja zakonczona z bledami integracji.',
|
||||
'checked_links' => $checkedLinks,
|
||||
'missing_links' => $missingLinks,
|
||||
'resolved_alerts' => $resolvedAlerts,
|
||||
'integrations' => count($activeIntegrations),
|
||||
'integration_failures' => $integrationFailures,
|
||||
'errors' => $errors,
|
||||
];
|
||||
}
|
||||
|
||||
private function nullableText(mixed $value): ?string
|
||||
{
|
||||
$text = trim((string) $value);
|
||||
return $text === '' ? null : $text;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user