feat: Implement Allegro Order Sync and Status Management

- Added AllegroOrderSyncStateRepository for managing sync state with Allegro orders.
- Introduced AllegroOrdersSyncService to handle the synchronization of orders from Allegro.
- Created AllegroStatusDiscoveryService to discover and store order statuses from Allegro.
- Developed AllegroStatusMappingRepository for managing status mappings between Allegro and OrderPro.
- Implemented AllegroStatusSyncService to facilitate status synchronization.
- Added CronSettingsController for managing cron job settings related to Allegro integration.
This commit is contained in:
2026-03-04 23:21:35 +01:00
parent 9ca79ca8d8
commit 7ac4293df4
40 changed files with 5758 additions and 31 deletions

View File

@@ -0,0 +1,703 @@
<?php
declare(strict_types=1);
namespace App\Modules\Settings;
use App\Core\Http\Request;
use App\Core\Http\Response;
use App\Core\I18n\Translator;
use App\Core\Security\Csrf;
use App\Core\Support\Flash;
use App\Core\View\Template;
use App\Modules\Auth\AuthService;
use App\Modules\Cron\CronRepository;
use DateInterval;
use DateTimeImmutable;
use RuntimeException;
use Throwable;
final class AllegroIntegrationController
{
private const OAUTH_STATE_SESSION_KEY = 'allegro_oauth_state';
private const ORDERS_IMPORT_JOB_TYPE = 'allegro_orders_import';
private const STATUS_SYNC_JOB_TYPE = 'allegro_status_sync';
private const ORDERS_IMPORT_DEFAULT_INTERVAL_SECONDS = 300;
private const ORDERS_IMPORT_DEFAULT_PRIORITY = 20;
private const ORDERS_IMPORT_DEFAULT_MAX_ATTEMPTS = 3;
private const STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO = 'allegro_to_orderpro';
private const STATUS_SYNC_DIRECTION_ORDERPRO_TO_ALLEGRO = 'orderpro_to_allegro';
private const STATUS_SYNC_DEFAULT_INTERVAL_MINUTES = 15;
private const ORDERS_IMPORT_DEFAULT_PAYLOAD = [
'max_pages' => 5,
'page_limit' => 50,
'max_orders' => 200,
];
private const OAUTH_SCOPES = [
AllegroOAuthClient::ORDERS_READ_SCOPE,
AllegroOAuthClient::SALE_OFFERS_READ_SCOPE,
];
public function __construct(
private readonly Template $template,
private readonly Translator $translator,
private readonly AuthService $auth,
private readonly AllegroIntegrationRepository $repository,
private readonly AllegroStatusMappingRepository $statusMappings,
private readonly OrderStatusRepository $orderStatuses,
private readonly CronRepository $cronRepository,
private readonly AllegroOAuthClient $oauthClient,
private readonly AllegroOrderImportService $orderImportService,
private readonly AllegroStatusDiscoveryService $statusDiscoveryService,
private readonly string $appUrl
) {
}
public function index(Request $request): Response
{
$settings = $this->repository->getSettings();
$tab = trim((string) $request->input('tab', 'integration'));
if (!in_array($tab, ['integration', 'statuses', 'settings'], true)) {
$tab = 'integration';
}
$defaultRedirectUri = $this->defaultRedirectUri();
if (trim((string) ($settings['redirect_uri'] ?? '')) === '') {
$settings['redirect_uri'] = $defaultRedirectUri;
}
$importIntervalSeconds = $this->currentImportIntervalSeconds();
$statusSyncDirection = $this->currentStatusSyncDirection();
$statusSyncIntervalMinutes = $this->currentStatusSyncIntervalMinutes();
$html = $this->template->render('settings/allegro', [
'title' => $this->translator->get('settings.allegro.title'),
'activeMenu' => 'settings',
'activeSettings' => 'allegro',
'user' => $this->auth->user(),
'csrfToken' => Csrf::token(),
'settings' => $settings,
'activeTab' => $tab,
'importIntervalSeconds' => $importIntervalSeconds,
'statusSyncDirection' => $statusSyncDirection,
'statusSyncIntervalMinutes' => $statusSyncIntervalMinutes,
'statusMappings' => $this->statusMappings->listMappings(),
'orderproStatuses' => $this->orderStatuses->listStatuses(),
'defaultRedirectUri' => $defaultRedirectUri,
'errorMessage' => (string) Flash::get('settings_error', ''),
'successMessage' => (string) Flash::get('settings_success', ''),
'warningMessage' => (string) Flash::get('settings_warning', ''),
], 'layouts/app');
return Response::html($html);
}
public function save(Request $request): Response
{
$csrfError = $this->validateCsrf((string) $request->input('_token', ''));
if ($csrfError !== null) {
return $csrfError;
}
$environment = trim((string) $request->input('environment', 'sandbox'));
if (!in_array($environment, ['sandbox', 'production'], true)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.environment_invalid'));
return Response::redirect('/settings/integrations/allegro');
}
$clientId = trim((string) $request->input('client_id', ''));
if ($clientId !== '' && mb_strlen($clientId) > 128) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.client_id_too_long'));
return Response::redirect('/settings/integrations/allegro');
}
$redirectUriInput = trim((string) $request->input('redirect_uri', ''));
$redirectUri = $redirectUriInput !== '' ? $redirectUriInput : $this->defaultRedirectUri();
if (!$this->isValidHttpUrl($redirectUri)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.redirect_uri_invalid'));
return Response::redirect('/settings/integrations/allegro');
}
$ordersFetchStartDate = trim((string) $request->input('orders_fetch_start_date', ''));
if ($ordersFetchStartDate !== '' && !$this->isValidDate($ordersFetchStartDate)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.orders_fetch_start_date_invalid'));
return Response::redirect('/settings/integrations/allegro');
}
try {
$this->repository->saveSettings([
'environment' => $environment,
'client_id' => $clientId,
'client_secret' => trim((string) $request->input('client_secret', '')),
'redirect_uri' => $redirectUri,
'orders_fetch_enabled' => (string) $request->input('orders_fetch_enabled', '0') === '1',
'orders_fetch_start_date' => $ordersFetchStartDate,
]);
Flash::set('settings_success', $this->translator->get('settings.allegro.flash.saved'));
} catch (Throwable $exception) {
Flash::set(
'settings_error',
$this->translator->get('settings.allegro.flash.save_failed') . ' ' . $exception->getMessage()
);
}
return Response::redirect('/settings/integrations/allegro');
}
public function saveImportSettings(Request $request): Response
{
$csrfError = $this->validateCsrf((string) $request->input('_token', ''));
if ($csrfError !== null) {
return $csrfError;
}
$intervalMinutesRaw = (int) $request->input('orders_import_interval_minutes', 5);
$intervalMinutes = max(1, min(1440, $intervalMinutesRaw));
if ($intervalMinutesRaw !== $intervalMinutes) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.orders_import_interval_invalid'));
return Response::redirect('/settings/integrations/allegro?tab=settings');
}
$statusSyncDirection = trim((string) $request->input(
'status_sync_direction',
self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO
));
if (!in_array($statusSyncDirection, $this->allowedStatusSyncDirections(), true)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.status_sync_direction_invalid'));
return Response::redirect('/settings/integrations/allegro?tab=settings');
}
$statusSyncIntervalRaw = (int) $request->input(
'status_sync_interval_minutes',
self::STATUS_SYNC_DEFAULT_INTERVAL_MINUTES
);
$statusSyncInterval = max(1, min(1440, $statusSyncIntervalRaw));
if ($statusSyncIntervalRaw !== $statusSyncInterval) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.status_sync_interval_invalid'));
return Response::redirect('/settings/integrations/allegro?tab=settings');
}
$existing = $this->findImportSchedule();
$priority = (int) ($existing['priority'] ?? self::ORDERS_IMPORT_DEFAULT_PRIORITY);
$maxAttempts = (int) ($existing['max_attempts'] ?? self::ORDERS_IMPORT_DEFAULT_MAX_ATTEMPTS);
$payload = is_array($existing['payload'] ?? null)
? (array) $existing['payload']
: self::ORDERS_IMPORT_DEFAULT_PAYLOAD;
$enabled = array_key_exists('enabled', $existing)
? (bool) $existing['enabled']
: true;
$statusSchedule = $this->findStatusSyncSchedule();
$statusPriority = (int) ($statusSchedule['priority'] ?? self::ORDERS_IMPORT_DEFAULT_PRIORITY);
$statusMaxAttempts = (int) ($statusSchedule['max_attempts'] ?? self::ORDERS_IMPORT_DEFAULT_MAX_ATTEMPTS);
$statusEnabled = array_key_exists('enabled', $statusSchedule)
? (bool) $statusSchedule['enabled']
: true;
try {
$this->cronRepository->upsertSchedule(
self::ORDERS_IMPORT_JOB_TYPE,
$intervalMinutes * 60,
$priority,
$maxAttempts,
$payload,
$enabled
);
$this->cronRepository->upsertSchedule(
self::STATUS_SYNC_JOB_TYPE,
$statusSyncInterval * 60,
$statusPriority,
$statusMaxAttempts,
null,
$statusEnabled
);
$this->cronRepository->upsertSetting('allegro_status_sync_direction', $statusSyncDirection);
$this->cronRepository->upsertSetting('allegro_status_sync_interval_minutes', (string) $statusSyncInterval);
Flash::set('settings_success', $this->translator->get('settings.allegro.flash.import_settings_saved'));
} catch (Throwable $exception) {
Flash::set(
'settings_error',
$this->translator->get('settings.allegro.flash.import_settings_save_failed') . ' ' . $exception->getMessage()
);
}
return Response::redirect('/settings/integrations/allegro?tab=settings');
}
public function saveStatusMapping(Request $request): Response
{
$csrfError = $this->validateCsrf((string) $request->input('_token', ''));
if ($csrfError !== null) {
return $csrfError;
}
$allegroStatusCode = strtolower(trim((string) $request->input('allegro_status_code', '')));
$orderproStatusCode = strtolower(trim((string) $request->input('orderpro_status_code', '')));
$allegroStatusName = trim((string) $request->input('allegro_status_name', ''));
if ($allegroStatusCode === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.allegro_status_required'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
if ($orderproStatusCode === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.orderpro_status_required'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
if (!$this->orderStatusCodeExists($orderproStatusCode)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.orderpro_status_not_found'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
try {
$this->statusMappings->upsertMapping($allegroStatusCode, $allegroStatusName !== '' ? $allegroStatusName : null, $orderproStatusCode);
Flash::set('settings_success', $this->translator->get('settings.allegro.statuses.flash.saved'));
} catch (Throwable $exception) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.save_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
public function saveStatusMappingsBulk(Request $request): Response
{
$csrfError = $this->validateCsrf((string) $request->input('_token', ''));
if ($csrfError !== null) {
return $csrfError;
}
$codes = $request->input('allegro_status_code', []);
$names = $request->input('allegro_status_name', []);
$selectedOrderproCodes = $request->input('orderpro_status_code', []);
if (!is_array($codes) || !is_array($names) || !is_array($selectedOrderproCodes)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.save_failed'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
try {
foreach ($codes as $index => $rawCode) {
$allegroStatusCode = strtolower(trim((string) $rawCode));
if ($allegroStatusCode === '') {
continue;
}
$allegroStatusName = trim((string) ($names[$index] ?? ''));
$orderproStatusCodeRaw = strtolower(trim((string) ($selectedOrderproCodes[$index] ?? '')));
$orderproStatusCode = $orderproStatusCodeRaw !== '' ? $orderproStatusCodeRaw : null;
if ($orderproStatusCode !== null && !$this->orderStatusCodeExists($orderproStatusCode)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.orderpro_status_not_found'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
$this->statusMappings->upsertMapping(
$allegroStatusCode,
$allegroStatusName !== '' ? $allegroStatusName : null,
$orderproStatusCode
);
}
Flash::set('settings_success', $this->translator->get('settings.allegro.statuses.flash.saved_bulk'));
} catch (Throwable $exception) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.save_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
public function deleteStatusMapping(Request $request): Response
{
$csrfError = $this->validateCsrf((string) $request->input('_token', ''));
if ($csrfError !== null) {
return $csrfError;
}
$mappingId = max(0, (int) $request->input('mapping_id', 0));
if ($mappingId <= 0) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.mapping_not_found'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
try {
$this->statusMappings->deleteMappingById($mappingId);
Flash::set('settings_success', $this->translator->get('settings.allegro.statuses.flash.deleted'));
} catch (Throwable $exception) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.delete_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
public function syncStatusesFromAllegro(Request $request): Response
{
$csrfError = $this->validateCsrf((string) $request->input('_token', ''));
if ($csrfError !== null) {
return $csrfError;
}
try {
$result = $this->statusDiscoveryService->discoverAndStoreStatuses(5, 100);
Flash::set(
'settings_success',
$this->translator->get('settings.allegro.statuses.flash.sync_ok', [
'discovered' => (string) ((int) ($result['discovered'] ?? 0)),
'samples' => (string) ((int) ($result['samples'] ?? 0)),
])
);
} catch (Throwable $exception) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.sync_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=statuses');
}
public function startOAuth(Request $request): Response
{
$csrfError = $this->validateCsrf((string) $request->input('_token', ''));
if ($csrfError !== null) {
return $csrfError;
}
try {
$credentials = $this->requireOAuthCredentials();
$state = bin2hex(random_bytes(24));
$_SESSION[self::OAUTH_STATE_SESSION_KEY] = $state;
$url = $this->oauthClient->buildAuthorizeUrl(
(string) $credentials['environment'],
(string) $credentials['client_id'],
(string) $credentials['redirect_uri'],
$state,
self::OAUTH_SCOPES
);
return Response::redirect($url);
} catch (Throwable $exception) {
Flash::set('settings_error', $exception->getMessage());
return Response::redirect('/settings/integrations/allegro');
}
}
public function oauthCallback(Request $request): Response
{
$error = trim((string) $request->input('error', ''));
if ($error !== '') {
$description = trim((string) $request->input('error_description', ''));
$message = $this->translator->get('settings.allegro.flash.oauth_failed');
if ($description !== '') {
$message .= ' ' . $description;
}
Flash::set('settings_error', $message);
return Response::redirect('/settings/integrations/allegro');
}
$state = trim((string) $request->input('state', ''));
$expectedState = trim((string) ($_SESSION[self::OAUTH_STATE_SESSION_KEY] ?? ''));
unset($_SESSION[self::OAUTH_STATE_SESSION_KEY]);
if ($state === '' || $expectedState === '' || !hash_equals($expectedState, $state)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.oauth_state_invalid'));
return Response::redirect('/settings/integrations/allegro');
}
$authorizationCode = trim((string) $request->input('code', ''));
if ($authorizationCode === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.oauth_code_missing'));
return Response::redirect('/settings/integrations/allegro');
}
try {
$credentials = $this->requireOAuthCredentials();
$token = $this->oauthClient->exchangeAuthorizationCode(
(string) $credentials['environment'],
(string) $credentials['client_id'],
(string) $credentials['client_secret'],
(string) $credentials['redirect_uri'],
$authorizationCode
);
$expiresAt = null;
if ((int) ($token['expires_in'] ?? 0) > 0) {
$expiresAt = (new DateTimeImmutable('now'))
->add(new DateInterval('PT' . (int) $token['expires_in'] . 'S'))
->format('Y-m-d H:i:s');
}
$this->repository->saveTokens(
(string) ($token['access_token'] ?? ''),
(string) ($token['refresh_token'] ?? ''),
(string) ($token['token_type'] ?? ''),
(string) ($token['scope'] ?? ''),
$expiresAt
);
Flash::set('settings_success', $this->translator->get('settings.allegro.flash.oauth_connected'));
} catch (Throwable $exception) {
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.oauth_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro');
}
public function importSingleOrder(Request $request): Response
{
$csrfError = $this->validateCsrf((string) $request->input('_token', ''));
if ($csrfError !== null) {
return $csrfError;
}
$checkoutFormId = trim((string) $request->input('checkout_form_id', ''));
if ($checkoutFormId === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.checkout_form_id_required'));
return Response::redirect('/settings/integrations/allegro');
}
try {
$result = $this->orderImportService->importSingleOrder($checkoutFormId);
$imageDiagnostics = is_array($result['image_diagnostics'] ?? null) ? $result['image_diagnostics'] : [];
Flash::set(
'settings_success',
$this->translator->get('settings.allegro.flash.import_single_ok', [
'source_order_id' => (string) ($result['source_order_id'] ?? $checkoutFormId),
'local_id' => (string) ((int) ($result['order_id'] ?? 0)),
'action' => !empty($result['created'])
? $this->translator->get('settings.allegro.import_action.created')
: $this->translator->get('settings.allegro.import_action.updated'),
]) . ' '
. $this->translator->get('settings.allegro.flash.import_single_media_summary', [
'with_image' => (string) ((int) ($imageDiagnostics['with_image'] ?? 0)),
'total_items' => (string) ((int) ($imageDiagnostics['total_items'] ?? 0)),
'without_image' => (string) ((int) ($imageDiagnostics['without_image'] ?? 0)),
])
);
$warningDetails = $this->buildImportImageWarningMessage($imageDiagnostics);
if ($warningDetails !== '') {
Flash::set('settings_warning', $warningDetails);
}
} catch (Throwable $exception) {
Flash::set(
'settings_error',
$this->translator->get('settings.allegro.flash.import_single_failed') . ' ' . $exception->getMessage()
);
}
return Response::redirect('/settings/integrations/allegro');
}
private function defaultRedirectUri(): string
{
$base = trim($this->appUrl);
if ($base === '') {
$base = 'http://localhost:8000';
}
return rtrim($base, '/') . '/settings/integrations/allegro/oauth/callback';
}
private function validateCsrf(string $token): ?Response
{
if (Csrf::validate($token)) {
return null;
}
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
return Response::redirect('/settings/integrations/allegro');
}
/**
* @return array<string, string>
*/
private function requireOAuthCredentials(): array
{
$credentials = $this->repository->getOAuthCredentials();
if ($credentials === null) {
throw new RuntimeException($this->translator->get('settings.allegro.flash.credentials_missing'));
}
return $credentials;
}
private function isValidHttpUrl(string $url): bool
{
$trimmed = trim($url);
if ($trimmed === '') {
return false;
}
if (filter_var($trimmed, FILTER_VALIDATE_URL) === false) {
return false;
}
$scheme = strtolower((string) parse_url($trimmed, PHP_URL_SCHEME));
return $scheme === 'http' || $scheme === 'https';
}
private function isValidDate(string $value): bool
{
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value) !== 1) {
return false;
}
$date = DateTimeImmutable::createFromFormat('Y-m-d', $value);
return $date instanceof DateTimeImmutable && $date->format('Y-m-d') === $value;
}
private function orderStatusCodeExists(string $code): bool
{
$needle = strtolower(trim($code));
if ($needle === '') {
return false;
}
foreach ($this->orderStatuses->listStatuses() as $row) {
$statusCode = strtolower(trim((string) ($row['code'] ?? '')));
if ($statusCode === $needle) {
return true;
}
}
return false;
}
/**
* @param array<string, mixed> $imageDiagnostics
*/
private function buildImportImageWarningMessage(array $imageDiagnostics): string
{
$withoutImage = (int) ($imageDiagnostics['without_image'] ?? 0);
if ($withoutImage <= 0) {
return '';
}
$reasonCountsRaw = $imageDiagnostics['reason_counts'] ?? [];
if (!is_array($reasonCountsRaw) || $reasonCountsRaw === []) {
return $this->translator->get('settings.allegro.flash.import_single_media_warning_generic', [
'without_image' => (string) $withoutImage,
]);
}
$parts = [];
foreach ($reasonCountsRaw as $reason => $countRaw) {
$count = (int) $countRaw;
if ($count <= 0) {
continue;
}
$parts[] = $this->reasonLabel((string) $reason) . ': ' . $count;
}
if ($parts === []) {
return $this->translator->get('settings.allegro.flash.import_single_media_warning_generic', [
'without_image' => (string) $withoutImage,
]);
}
return $this->translator->get('settings.allegro.flash.import_single_media_warning', [
'without_image' => (string) $withoutImage,
'reasons' => implode(', ', $parts),
]);
}
private function reasonLabel(string $reasonCode): string
{
return match ($reasonCode) {
'missing_offer_id' => 'brak ID oferty',
'missing_in_checkout_form' => 'brak obrazka w checkout form',
'missing_in_offer_api' => 'brak obrazka w API oferty',
'offer_api_access_denied_403' => 'brak uprawnien API ofert (403)',
'offer_api_unauthorized_401' => 'token nieautoryzowany dla API ofert (401)',
'offer_api_not_found_404' => 'oferta nie znaleziona (404)',
'offer_api_request_failed' => 'blad zapytania do API oferty',
default => str_starts_with($reasonCode, 'offer_api_http_')
? 'blad API oferty (' . str_replace('offer_api_http_', '', $reasonCode) . ')'
: $reasonCode,
};
}
private function currentImportIntervalSeconds(): int
{
$schedule = $this->findImportSchedule();
$value = (int) ($schedule['interval_seconds'] ?? self::ORDERS_IMPORT_DEFAULT_INTERVAL_SECONDS);
return max(60, min(86400, $value));
}
/**
* @return array<string, mixed>
*/
private function findImportSchedule(): array
{
try {
$schedules = $this->cronRepository->listSchedules();
} catch (Throwable) {
return [];
}
foreach ($schedules as $schedule) {
if (!is_array($schedule)) {
continue;
}
if ((string) ($schedule['job_type'] ?? '') !== self::ORDERS_IMPORT_JOB_TYPE) {
continue;
}
return $schedule;
}
return [];
}
/**
* @return array<string, mixed>
*/
private function findStatusSyncSchedule(): array
{
try {
$schedules = $this->cronRepository->listSchedules();
} catch (Throwable) {
return [];
}
foreach ($schedules as $schedule) {
if (!is_array($schedule)) {
continue;
}
if ((string) ($schedule['job_type'] ?? '') !== self::STATUS_SYNC_JOB_TYPE) {
continue;
}
return $schedule;
}
return [];
}
private function currentStatusSyncDirection(): string
{
$value = trim($this->cronRepository->getStringSetting(
'allegro_status_sync_direction',
self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO
));
if (!in_array($value, $this->allowedStatusSyncDirections(), true)) {
return self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO;
}
return $value;
}
private function currentStatusSyncIntervalMinutes(): int
{
return $this->cronRepository->getIntSetting(
'allegro_status_sync_interval_minutes',
self::STATUS_SYNC_DEFAULT_INTERVAL_MINUTES,
1,
1440
);
}
/**
* @return array<int, string>
*/
private function allowedStatusSyncDirections(): array
{
return [
self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO,
self::STATUS_SYNC_DIRECTION_ORDERPRO_TO_ALLEGRO,
];
}
}