- Introduced ShipmentProviderInterface to define the contract for shipment providers. - Implemented ShipmentProviderRegistry to manage and retrieve shipment providers. - Added a new tool for probing Apaczka order_send payload variants, enhancing debugging capabilities.
744 lines
42 KiB
PHP
744 lines
42 KiB
PHP
<?php
|
|
$list = is_array($rows ?? null) ? $rows : [];
|
|
$selected = is_array($selectedIntegration ?? null) ? $selectedIntegration : null;
|
|
$formValues = is_array($form ?? null) ? $form : [];
|
|
$statusRows = is_array($statusRows ?? null) ? $statusRows : [];
|
|
$orderproStatuses = is_array($orderproStatuses ?? null) ? $orderproStatuses : [];
|
|
$ordersImportIntervalMinutes = max(1, (int) ($ordersImportIntervalMinutes ?? 5));
|
|
$statusSyncIntervalMinutes = max(1, (int) ($statusSyncIntervalMinutes ?? 15));
|
|
$paymentSyncIntervalMinutes = max(1, (int) ($paymentSyncIntervalMinutes ?? 10));
|
|
$activeTab = (string) ($activeTab ?? 'integration');
|
|
$isEdit = ((int) ($formValues['integration_id'] ?? 0)) > 0;
|
|
$selectedIntegrationId = (int) ($formValues['integration_id'] ?? 0);
|
|
$selectedPaymentSyncCodes = is_array($formValues['payment_sync_status_codes'] ?? null) ? $formValues['payment_sync_status_codes'] : [];
|
|
$dmMappings = is_array($deliveryMappings ?? null) ? $deliveryMappings : [];
|
|
$dmOrderMethods = is_array($orderDeliveryMethods ?? null) ? $orderDeliveryMethods : [];
|
|
$dmAllegroServices = is_array($allegroDeliveryServices ?? null) ? $allegroDeliveryServices : [];
|
|
$dmApaczkaServices = is_array($apaczkaDeliveryServices ?? null) ? $apaczkaDeliveryServices : [];
|
|
$dmInpostServices = is_array($inpostDeliveryServices ?? null) ? $inpostDeliveryServices : [];
|
|
$dmServicesError = (string) ($allegroDeliveryServicesError ?? '');
|
|
$dmMappingsByMethod = [];
|
|
foreach ($dmMappings as $dm) {
|
|
if (!is_array($dm)) {
|
|
continue;
|
|
}
|
|
$dmMappingsByMethod[trim((string) ($dm['order_delivery_method'] ?? ''))] = $dm;
|
|
}
|
|
?>
|
|
|
|
<section class="card">
|
|
<h2 class="section-title"><?= $e($t('settings.integrations.title')) ?></h2>
|
|
<p class="muted mt-12"><?= $e($t('settings.integrations.description')) ?></p>
|
|
|
|
<?php if (!empty($errorMessage)): ?>
|
|
<div class="alert alert--danger mt-12" role="alert"><?= $e((string) $errorMessage) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!empty($successMessage)): ?>
|
|
<div class="alert alert--success mt-12" role="status"><?= $e((string) $successMessage) ?></div>
|
|
<?php endif; ?>
|
|
</section>
|
|
|
|
<section class="card mt-16">
|
|
<?php if ($list !== []): ?>
|
|
<div class="shoppro-tabs-toolbar">
|
|
<label class="form-field shoppro-tabs-toolbar__field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.selector.integration')) ?></span>
|
|
<select class="form-control" id="shoppro-integration-select">
|
|
<?php foreach ($list as $item): ?>
|
|
<?php $rowId = (int) ($item['id'] ?? 0); ?>
|
|
<?php if ($rowId <= 0) continue; ?>
|
|
<option value="<?= $e((string) $rowId) ?>"<?= $rowId === $selectedIntegrationId ? ' selected' : '' ?>>
|
|
<?= $e((string) ($item['name'] ?? ('#' . $rowId))) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</label>
|
|
<div class="shoppro-tabs-toolbar__actions">
|
|
<a href="/settings/integrations/shoppro?new=1" class="btn btn--secondary btn--sm"><?= $e($t('settings.integrations.actions.new')) ?></a>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<nav class="content-tabs-nav" aria-label="<?= $e($t('settings.integrations.tabs.label')) ?>">
|
|
<button type="button" class="content-tab-btn<?= $activeTab === 'integration' ? ' is-active' : '' ?>" data-tab-target="shoppro-tab-integration">
|
|
<?= $e($t('settings.integrations.tabs.integration')) ?>
|
|
</button>
|
|
<button type="button" class="content-tab-btn<?= $activeTab === 'statuses' ? ' is-active' : '' ?>" data-tab-target="shoppro-tab-statuses">
|
|
<?= $e($t('settings.integrations.tabs.statuses')) ?>
|
|
</button>
|
|
<button type="button" class="content-tab-btn<?= $activeTab === 'settings' ? ' is-active' : '' ?>" data-tab-target="shoppro-tab-settings">
|
|
<?= $e($t('settings.integrations.tabs.settings')) ?>
|
|
</button>
|
|
<button type="button" class="content-tab-btn<?= $activeTab === 'delivery' ? ' is-active' : '' ?>" data-tab-target="shoppro-tab-delivery">
|
|
<?= $e($t('settings.integrations.tabs.delivery')) ?>
|
|
</button>
|
|
</nav>
|
|
|
|
<div class="content-tab-panel<?= $activeTab === 'integration' ? ' is-active' : '' ?>" data-tab-panel="shoppro-tab-integration">
|
|
<section class="mt-16 integrations-overview">
|
|
<h3 class="section-title"><?= $e($t('settings.integrations.list_title')) ?></h3>
|
|
<div class="table-wrap mt-12">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th><?= $e($t('settings.integrations.fields.name')) ?></th>
|
|
<th><?= $e($t('settings.integrations.fields.base_url')) ?></th>
|
|
<th><?= $e($t('settings.integrations.fields.active')) ?></th>
|
|
<th><?= $e($t('settings.integrations.fields.last_test')) ?></th>
|
|
<th><?= $e($t('settings.integrations.fields.actions')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if ($list === []): ?>
|
|
<tr>
|
|
<td colspan="6" class="muted"><?= $e($t('settings.integrations.empty')) ?></td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($list as $item): ?>
|
|
<?php
|
|
$status = (string) ($item['last_test_status'] ?? '');
|
|
$statusLabel = $status === 'ok'
|
|
? $t('settings.integrations.test_status.ok')
|
|
: ($status === 'error' ? $t('settings.integrations.test_status.error') : $t('settings.integrations.test_status.never'));
|
|
?>
|
|
<tr>
|
|
<td><?= $e((string) ($item['id'] ?? 0)) ?></td>
|
|
<td><?= $e((string) ($item['name'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($item['base_url'] ?? '')) ?></td>
|
|
<td>
|
|
<?php if (!empty($item['is_active'])): ?>
|
|
<span class="status-pill is-active"><?= $e($t('settings.integrations.active.yes')) ?></span>
|
|
<?php else: ?>
|
|
<span class="status-pill"><?= $e($t('settings.integrations.active.no')) ?></span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<div><?= $e($statusLabel) ?></div>
|
|
<?php if (!empty($item['last_test_at'])): ?>
|
|
<small class="muted">
|
|
<?= $e((string) $item['last_test_at']) ?>
|
|
<?php if (($item['last_test_http_code'] ?? null) !== null): ?> | HTTP <?= $e((string) ($item['last_test_http_code'])) ?><?php endif; ?>
|
|
</small>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<div class="table-row-actions">
|
|
<a class="btn btn--secondary btn--sm" href="/settings/integrations/shoppro?id=<?= $e((string) ($item['id'] ?? 0)) ?>">
|
|
<?= $e($t('settings.integrations.actions.edit')) ?>
|
|
</a>
|
|
<form action="/settings/integrations/shoppro/test" method="post">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="integration_id" value="<?= $e((string) ($item['id'] ?? 0)) ?>">
|
|
<input type="hidden" name="tab" value="integration">
|
|
<button type="submit" class="btn btn--primary btn--sm"><?= $e($t('settings.integrations.actions.test')) ?></button>
|
|
</form>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="mt-16">
|
|
<h3 class="section-title"><?= $e($isEdit ? $t('settings.integrations.edit_title') : $t('settings.integrations.create_title')) ?></h3>
|
|
<form class="statuses-form mt-16" action="/settings/integrations/shoppro/save" method="post" novalidate>
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="integration_id" value="<?= $e((string) ($formValues['integration_id'] ?? 0)) ?>">
|
|
<input type="hidden" name="tab" value="integration">
|
|
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.fields.name')) ?></span>
|
|
<input class="form-control" type="text" name="name" value="<?= $e((string) ($formValues['name'] ?? '')) ?>" required>
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.fields.base_url')) ?></span>
|
|
<input class="form-control" type="url" name="base_url" value="<?= $e((string) ($formValues['base_url'] ?? '')) ?>" placeholder="https://shoppro.project-dc.pl/" required>
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.fields.api_key')) ?></span>
|
|
<input class="form-control" type="password" name="api_key" value="" placeholder="<?= $e($isEdit ? $t('settings.integrations.api_key_placeholder_edit') : '') ?>" autocomplete="new-password">
|
|
<?php if ($isEdit): ?>
|
|
<span class="muted"><?= $e(($selected['has_api_key'] ?? false) ? $t('settings.integrations.api_key_saved') : $t('settings.integrations.api_key_missing')) ?></span>
|
|
<?php endif; ?>
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.fields.timeout_seconds')) ?></span>
|
|
<input class="form-control" type="number" min="1" max="120" name="timeout_seconds" value="<?= $e((string) ($formValues['timeout_seconds'] ?? 10)) ?>">
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label">
|
|
<input type="checkbox" name="is_active" value="1"<?= ((int) ($formValues['is_active'] ?? 1)) === 1 ? ' checked' : '' ?>>
|
|
<?= $e($t('settings.integrations.fields.active_checkbox')) ?>
|
|
</span>
|
|
</label>
|
|
|
|
<div class="form-actions mt-12">
|
|
<button type="submit" class="btn btn--primary"><?= $e($t('settings.integrations.actions.save')) ?></button>
|
|
<a href="/settings/integrations/shoppro?new=1" class="btn btn--secondary"><?= $e($t('settings.integrations.actions.new')) ?></a>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
</div>
|
|
|
|
<div class="content-tab-panel<?= $activeTab === 'statuses' ? ' is-active' : '' ?>" data-tab-panel="shoppro-tab-statuses">
|
|
<section class="mt-16">
|
|
<h3 class="section-title"><?= $e($t('settings.integrations.statuses.title')) ?></h3>
|
|
<p class="muted mt-12"><?= $e($t('settings.integrations.statuses.description')) ?></p>
|
|
|
|
<?php if (!$isEdit && $list === []): ?>
|
|
<p class="muted mt-12"><?= $e($t('settings.integrations.statuses.select_integration_first')) ?></p>
|
|
<?php else: ?>
|
|
<form class="mt-12" action="/settings/integrations/shoppro/statuses/sync" method="post">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="integration_id" value="<?= $e((string) ($formValues['integration_id'] ?? 0)) ?>">
|
|
<button type="submit" class="btn btn--secondary"><?= $e($t('settings.integrations.statuses.actions.sync')) ?></button>
|
|
</form>
|
|
|
|
<form class="mt-12" action="/settings/integrations/shoppro/statuses/save" method="post">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="integration_id" value="<?= $e((string) ($formValues['integration_id'] ?? 0)) ?>">
|
|
<div class="table-wrap mt-12">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th><?= $e($t('settings.order_statuses.fields.shoppro_code')) ?></th>
|
|
<th><?= $e($t('settings.order_statuses.fields.shoppro_name')) ?></th>
|
|
<th><?= $e($t('settings.order_statuses.fields.orderpro_status')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if ($statusRows === []): ?>
|
|
<tr>
|
|
<td colspan="3" class="muted"><?= $e($t('settings.integrations.statuses.empty')) ?></td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($statusRows as $row): ?>
|
|
<?php
|
|
$shopCode = (string) ($row['shoppro_status_code'] ?? '');
|
|
$shopName = (string) ($row['shoppro_status_name'] ?? '');
|
|
$selectedOrderpro = strtolower(trim((string) ($row['orderpro_status_code'] ?? '')));
|
|
?>
|
|
<tr>
|
|
<td>
|
|
<code><?= $e($shopCode) ?></code>
|
|
<input type="hidden" name="shoppro_status_code[]" value="<?= $e($shopCode) ?>">
|
|
</td>
|
|
<td>
|
|
<?= $e($shopName) ?>
|
|
<input type="hidden" name="shoppro_status_name[]" value="<?= $e($shopName) ?>">
|
|
</td>
|
|
<td>
|
|
<select class="form-control" name="orderpro_status_code[]">
|
|
<option value=""><?= $e($t('settings.order_statuses.fields.no_mapping')) ?></option>
|
|
<?php foreach ($orderproStatuses as $status): ?>
|
|
<?php $statusCode = strtolower(trim((string) ($status['code'] ?? ''))); ?>
|
|
<?php if ($statusCode === '') continue; ?>
|
|
<option value="<?= $e($statusCode) ?>"<?= $selectedOrderpro === $statusCode ? ' selected' : '' ?>>
|
|
<?= $e((string) ($status['name'] ?? $statusCode)) ?> (<?= $e($statusCode) ?>)
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php if ($statusRows !== []): ?>
|
|
<div class="form-actions mt-12">
|
|
<button type="submit" class="btn btn--primary"><?= $e($t('settings.order_statuses.actions.save')) ?></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
</form>
|
|
<?php endif; ?>
|
|
</section>
|
|
</div>
|
|
|
|
<div class="content-tab-panel<?= $activeTab === 'settings' ? ' is-active' : '' ?>" data-tab-panel="shoppro-tab-settings">
|
|
<section class="mt-16">
|
|
<h3 class="section-title"><?= $e($t('settings.integrations.settings.title')) ?></h3>
|
|
<p class="muted mt-12"><?= $e($t('settings.integrations.settings.description')) ?></p>
|
|
|
|
<?php if (!$isEdit && $list === []): ?>
|
|
<p class="muted mt-12"><?= $e($t('settings.integrations.settings.select_integration_first')) ?></p>
|
|
<?php else: ?>
|
|
<form class="statuses-form mt-12" action="/settings/integrations/shoppro/save" method="post" novalidate>
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="integration_id" value="<?= $e((string) ($formValues['integration_id'] ?? 0)) ?>">
|
|
<input type="hidden" name="tab" value="settings">
|
|
<input type="hidden" name="name" value="<?= $e((string) ($formValues['name'] ?? '')) ?>">
|
|
<input type="hidden" name="base_url" value="<?= $e((string) ($formValues['base_url'] ?? '')) ?>">
|
|
<input type="hidden" name="timeout_seconds" value="<?= $e((string) ($formValues['timeout_seconds'] ?? 10)) ?>">
|
|
<input type="hidden" name="is_active" value="<?= $e(((int) ($formValues['is_active'] ?? 1)) === 1 ? '1' : '0') ?>">
|
|
|
|
<div class="integration-settings-group">
|
|
<div class="integration-settings-group__head">
|
|
<h4 class="integration-settings-group__title"><?= $e($t('settings.integrations.settings.orders_group_title')) ?></h4>
|
|
<p class="muted integration-settings-group__desc"><?= $e($t('settings.integrations.settings.orders_group_description')) ?></p>
|
|
</div>
|
|
<div class="integration-settings-group__grid">
|
|
<label class="form-field integration-settings-group__full">
|
|
<span class="field-label">
|
|
<input type="checkbox" name="orders_fetch_enabled" value="1"<?= ((int) ($formValues['orders_fetch_enabled'] ?? 0)) === 1 ? ' checked' : '' ?>>
|
|
<?= $e($t('settings.integrations.fields.orders_fetch_enabled_checkbox')) ?>
|
|
</span>
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.fields.orders_fetch_start_date')) ?></span>
|
|
<input class="form-control" type="date" name="orders_fetch_start_date" value="<?= $e((string) ($formValues['orders_fetch_start_date'] ?? '')) ?>">
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.settings.orders_import_interval_minutes')) ?></span>
|
|
<input class="form-control" type="number" min="1" max="1440" name="orders_import_interval_minutes" value="<?= $e((string) $ordersImportIntervalMinutes) ?>">
|
|
<span class="muted"><?= $e($t('settings.integrations.settings.orders_import_interval_hint')) ?></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="integration-settings-group">
|
|
<div class="integration-settings-group__head">
|
|
<h4 class="integration-settings-group__title"><?= $e($t('settings.integrations.settings.statuses_group_title')) ?></h4>
|
|
<p class="muted integration-settings-group__desc"><?= $e($t('settings.integrations.settings.statuses_group_description')) ?></p>
|
|
</div>
|
|
<div class="integration-settings-group__grid">
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.fields.order_status_sync_direction')) ?></span>
|
|
<select class="form-control" name="order_status_sync_direction">
|
|
<?php $syncDirection = (string) ($formValues['order_status_sync_direction'] ?? 'shoppro_to_orderpro'); ?>
|
|
<option value="shoppro_to_orderpro"<?= $syncDirection === 'shoppro_to_orderpro' ? ' selected' : '' ?>>
|
|
<?= $e($t('settings.integrations.fields.order_status_sync_direction_shoppro_to_orderpro')) ?>
|
|
</option>
|
|
<option value="orderpro_to_shoppro"<?= $syncDirection === 'orderpro_to_shoppro' ? ' selected' : '' ?>>
|
|
<?= $e($t('settings.integrations.fields.order_status_sync_direction_orderpro_to_shoppro')) ?>
|
|
</option>
|
|
</select>
|
|
<span class="muted"><?= $e($t('settings.integrations.settings.status_sync_direction_hint')) ?></span>
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.settings.status_sync_interval_minutes')) ?></span>
|
|
<input class="form-control" type="number" min="1" max="1440" name="status_sync_interval_minutes" value="<?= $e((string) $statusSyncIntervalMinutes) ?>">
|
|
<span class="muted"><?= $e($t('settings.integrations.settings.status_sync_interval_hint')) ?></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="integration-settings-group">
|
|
<div class="integration-settings-group__head">
|
|
<h4 class="integration-settings-group__title"><?= $e($t('settings.integrations.settings.payment_group_title')) ?></h4>
|
|
<p class="muted integration-settings-group__desc"><?= $e($t('settings.integrations.settings.payment_group_description')) ?></p>
|
|
</div>
|
|
<div class="integration-settings-group__grid">
|
|
<label class="form-field">
|
|
<span class="field-label"><?= $e($t('settings.integrations.settings.payment_sync_interval_minutes')) ?></span>
|
|
<input class="form-control" type="number" min="1" max="1440" name="payment_sync_interval_minutes" value="<?= $e((string) $paymentSyncIntervalMinutes) ?>">
|
|
<span class="muted"><?= $e($t('settings.integrations.settings.payment_sync_interval_hint')) ?></span>
|
|
</label>
|
|
|
|
<fieldset class="form-field integration-settings-group__full integration-settings-checkboxes">
|
|
<legend class="field-label"><?= $e($t('settings.integrations.settings.payment_sync_status_codes')) ?></legend>
|
|
<span class="muted"><?= $e($t('settings.integrations.settings.payment_sync_status_codes_hint')) ?></span>
|
|
<div class="integration-settings-checkboxes__list mt-12">
|
|
<?php foreach ($orderproStatuses as $status): ?>
|
|
<?php $statusCode = strtolower(trim((string) ($status['code'] ?? ''))); ?>
|
|
<?php if ($statusCode === '') continue; ?>
|
|
<?php $isChecked = in_array($statusCode, $selectedPaymentSyncCodes, true); ?>
|
|
<label class="integration-settings-checkboxes__item">
|
|
<input type="checkbox" name="payment_sync_status_codes[]" value="<?= $e($statusCode) ?>"<?= $isChecked ? ' checked' : '' ?>>
|
|
<span><?= $e((string) ($status['name'] ?? $statusCode)) ?> (<?= $e($statusCode) ?>)</span>
|
|
</label>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button type="submit" class="btn btn--primary"><?= $e($t('settings.integrations.actions.save')) ?></button>
|
|
</div>
|
|
</form>
|
|
<?php endif; ?>
|
|
</section>
|
|
</div>
|
|
|
|
<div class="content-tab-panel<?= $activeTab === 'delivery' ? ' is-active' : '' ?>" data-tab-panel="shoppro-tab-delivery">
|
|
<section class="mt-16">
|
|
<h3 class="section-title"><?= $e($t('settings.integrations.delivery.title')) ?></h3>
|
|
<p class="muted mt-12"><?= $e($t('settings.integrations.delivery.description')) ?></p>
|
|
|
|
<?php if (!$isEdit): ?>
|
|
<p class="muted mt-12"><?= $e($t('settings.integrations.delivery.select_integration_first')) ?></p>
|
|
<?php else: ?>
|
|
<?php if ($dmServicesError !== ''): ?>
|
|
<div class="alert alert--danger mt-12"><?= $e($dmServicesError) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($dmOrderMethods === []): ?>
|
|
<p class="muted mt-12"><?= $e($t('settings.integrations.delivery.empty_orders')) ?></p>
|
|
<?php else: ?>
|
|
<form action="/settings/integrations/shoppro/delivery/save" method="post">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="integration_id" value="<?= $e((string) $selectedIntegrationId) ?>">
|
|
<div class="table-wrap table-wrap--visible mt-12">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th><?= $e($t('settings.integrations.delivery.fields.order_method')) ?></th>
|
|
<th><?= $e($t('settings.integrations.delivery.fields.carrier')) ?></th>
|
|
<th><?= $e($t('settings.integrations.delivery.fields.allegro_service')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($dmOrderMethods as $rowIdx => $orderMethod): ?>
|
|
<?php
|
|
$methodName = trim((string) $orderMethod);
|
|
$currentMapping = $dmMappingsByMethod[$methodName] ?? null;
|
|
$currentProvider = $currentMapping !== null ? trim((string) ($currentMapping['provider'] ?? 'allegro_wza')) : '';
|
|
$currentMethodId = $currentMapping !== null ? trim((string) ($currentMapping['provider_service_id'] ?? '')) : '';
|
|
$currentServiceName = $currentMapping !== null ? trim((string) ($currentMapping['provider_service_name'] ?? '')) : '';
|
|
$currentProviderCarrierId = $currentMapping !== null ? trim((string) ($currentMapping['provider_carrier_id'] ?? '')) : '';
|
|
$currentCarrier = '';
|
|
if ($currentProvider === 'apaczka') {
|
|
$currentCarrier = 'apaczka';
|
|
} elseif (stripos($currentProviderCarrierId, 'inpost') !== false) {
|
|
$currentCarrier = 'inpost';
|
|
} elseif ($currentMethodId !== '') {
|
|
$currentCarrier = 'allegro';
|
|
}
|
|
?>
|
|
<tr data-dm-row="<?= $rowIdx ?>">
|
|
<td>
|
|
<strong><?= $e($methodName) ?></strong>
|
|
<input type="hidden" name="order_delivery_method[]" value="<?= $e($methodName) ?>">
|
|
</td>
|
|
<td>
|
|
<select class="form-control dm-carrier-select" name="carrier[]" data-row="<?= $rowIdx ?>">
|
|
<option value="">-- <?= $e($t('settings.integrations.delivery.fields.no_mapping')) ?> --</option>
|
|
<option value="allegro"<?= $currentCarrier === 'allegro' && $currentMethodId !== '' ? ' selected' : '' ?>>Allegro</option>
|
|
<option value="inpost"<?= $currentCarrier === 'inpost' ? ' selected' : '' ?>>InPost</option>
|
|
<option value="apaczka"<?= $currentCarrier === 'apaczka' ? ' selected' : '' ?>>Apaczka</option>
|
|
</select>
|
|
</td>
|
|
<td>
|
|
<div class="dm-service-wrap" data-row="<?= $rowIdx ?>">
|
|
<input type="hidden" name="allegro_delivery_method_id[]" class="dm-hidden-method-id" value="<?= $e($currentProvider !== 'apaczka' ? $currentMethodId : '') ?>">
|
|
<input type="hidden" name="apaczka_delivery_method_id[]" class="dm-hidden-apaczka-method-id" value="<?= $e($currentProvider === 'apaczka' ? $currentMethodId : '') ?>">
|
|
<input type="hidden" name="allegro_credentials_id[]" class="dm-hidden-credentials-id" value="<?= $e(trim((string) ($currentMapping['provider_account_id'] ?? ''))) ?>">
|
|
<input type="hidden" name="allegro_carrier_id[]" class="dm-hidden-carrier-id" value="<?= $e($currentProviderCarrierId) ?>">
|
|
<input type="hidden" name="allegro_service_name[]" class="dm-hidden-service-name" value="<?= $e($currentServiceName) ?>">
|
|
|
|
<div class="dm-allegro-panel dm-searchable-select" data-current-id="<?= $e($currentCarrier === 'allegro' ? $currentMethodId : '') ?>" data-current-name="<?= $e($currentCarrier === 'allegro' ? $currentServiceName : '') ?>" style="<?= $currentCarrier !== 'allegro' ? 'display:none' : '' ?>">
|
|
<input type="text" class="form-control dm-search-input" placeholder="<?= $e($t('settings.integrations.delivery.fields.search_placeholder')) ?>" value="<?= $e($currentCarrier === 'allegro' ? $currentServiceName : '') ?>" autocomplete="off">
|
|
<div class="searchable-select__dropdown dm-dropdown">
|
|
<div class="searchable-select__option dm-option-clear" data-value="" data-label="" data-credentials-id="" data-carrier-id="">
|
|
<em class="muted">-- <?= $e($t('settings.integrations.delivery.fields.no_mapping')) ?> --</em>
|
|
</div>
|
|
<?php foreach ($dmAllegroServices as $svc): ?>
|
|
<?php
|
|
if (!is_array($svc)) {
|
|
continue;
|
|
}
|
|
$svcId = is_array($svc['id'] ?? null) ? $svc['id'] : [];
|
|
$svcMethodId = trim((string) ($svcId['deliveryMethodId'] ?? ''));
|
|
$svcCredentialsId = trim((string) ($svcId['credentialsId'] ?? ''));
|
|
$svcName = trim((string) ($svc['name'] ?? ''));
|
|
$svcCarrierId = trim((string) ($svc['carrierId'] ?? ''));
|
|
$svcOwner = trim((string) ($svc['owner'] ?? ''));
|
|
$svcLabel = $svcName . ' (' . $svcOwner . ')';
|
|
?>
|
|
<div class="searchable-select__option"
|
|
data-value="<?= $e($svcMethodId) ?>"
|
|
data-label="<?= $e($svcLabel) ?>"
|
|
data-credentials-id="<?= $e($svcCredentialsId) ?>"
|
|
data-carrier-id="<?= $e($svcCarrierId) ?>">
|
|
<?= $e($svcName) ?> <span class="muted">(<?= $e($svcOwner) ?>)</span>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="dm-apaczka-panel dm-searchable-select" data-provider="apaczka" data-current-id="<?= $e($currentCarrier === 'apaczka' ? $currentMethodId : '') ?>" data-current-name="<?= $e($currentCarrier === 'apaczka' ? $currentServiceName : '') ?>" style="<?= $currentCarrier !== 'apaczka' ? 'display:none' : '' ?>">
|
|
<?php if ($dmApaczkaServices === []): ?>
|
|
<div class="muted">Brak uslug Apaczka (sprawdz konfiguracje App ID/App Secret).</div>
|
|
<?php else: ?>
|
|
<input type="text" class="form-control dm-search-input" placeholder="<?= $e($t('settings.integrations.delivery.fields.search_placeholder')) ?>" value="<?= $e($currentCarrier === 'apaczka' ? $currentServiceName : '') ?>" autocomplete="off">
|
|
<div class="searchable-select__dropdown dm-dropdown">
|
|
<div class="searchable-select__option dm-option-clear" data-value="" data-label="" data-credentials-id="" data-carrier-id="">
|
|
<em class="muted">-- <?= $e($t('settings.integrations.delivery.fields.no_mapping')) ?> --</em>
|
|
</div>
|
|
<?php foreach ($dmApaczkaServices as $aSvc): ?>
|
|
<?php
|
|
if (!is_array($aSvc)) {
|
|
continue;
|
|
}
|
|
$aSvcId = trim((string) ($aSvc['service_id'] ?? $aSvc['id'] ?? ''));
|
|
$aSvcName = trim((string) ($aSvc['name'] ?? ''));
|
|
$aSvcCarrier = trim((string) ($aSvc['supplier'] ?? $aSvc['carrier_code'] ?? ''));
|
|
$aSvcLabel = $aSvcName !== '' ? $aSvcName : ('ID ' . $aSvcId);
|
|
?>
|
|
<div class="searchable-select__option"
|
|
data-value="<?= $e($aSvcId) ?>"
|
|
data-label="<?= $e($aSvcLabel) ?>"
|
|
data-credentials-id=""
|
|
data-carrier-id="<?= $e($aSvcCarrier) ?>">
|
|
<?= $e($aSvcLabel) ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="dm-inpost-panel dm-searchable-select" data-provider="inpost" data-current-id="<?= $e($currentCarrier === 'inpost' ? $currentMethodId : '') ?>" data-current-name="<?= $e($currentCarrier === 'inpost' ? $currentServiceName : '') ?>" style="<?= $currentCarrier !== 'inpost' ? 'display:none' : '' ?>">
|
|
<?php if ($dmInpostServices === []): ?>
|
|
<div class="muted"><?= $e($t('settings.integrations.delivery.no_inpost_services')) ?></div>
|
|
<?php else: ?>
|
|
<input type="text" class="form-control dm-search-input" placeholder="<?= $e($t('settings.integrations.delivery.fields.search_placeholder')) ?>" value="<?= $e($currentCarrier === 'inpost' ? $currentServiceName : '') ?>" autocomplete="off">
|
|
<div class="searchable-select__dropdown dm-dropdown">
|
|
<div class="searchable-select__option dm-option-clear" data-value="" data-label="" data-credentials-id="" data-carrier-id="">
|
|
<em class="muted">-- <?= $e($t('settings.integrations.delivery.fields.no_mapping')) ?> --</em>
|
|
</div>
|
|
<?php foreach ($dmInpostServices as $inSvc): ?>
|
|
<?php
|
|
if (!is_array($inSvc)) {
|
|
continue;
|
|
}
|
|
$inSvcId = is_array($inSvc['id'] ?? null) ? $inSvc['id'] : [];
|
|
$inSvcMethodId = trim((string) ($inSvcId['deliveryMethodId'] ?? ''));
|
|
$inSvcCredentialsId = trim((string) ($inSvcId['credentialsId'] ?? ''));
|
|
$inSvcCarrierId = trim((string) ($inSvc['carrierId'] ?? ''));
|
|
$inSvcName = trim((string) ($inSvc['name'] ?? ''));
|
|
?>
|
|
<div class="searchable-select__option"
|
|
data-value="<?= $e($inSvcMethodId) ?>"
|
|
data-label="<?= $e($inSvcName) ?>"
|
|
data-credentials-id="<?= $e($inSvcCredentialsId) ?>"
|
|
data-carrier-id="<?= $e($inSvcCarrierId) ?>">
|
|
<?= $e($inSvcName) ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="dm-empty-panel muted" style="<?= $currentCarrier !== '' ? 'display:none' : ($currentMethodId !== '' ? 'display:none' : '') ?>">
|
|
<?= $e($t('settings.integrations.delivery.fields.select_carrier_first')) ?>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="form-actions mt-12">
|
|
<button type="submit" class="btn btn--primary"><?= $e($t('settings.integrations.delivery.actions.save')) ?></button>
|
|
</div>
|
|
</form>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
</section>
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
(function () {
|
|
var tabs = document.querySelectorAll('[data-tab-target]');
|
|
var panels = document.querySelectorAll('[data-tab-panel]');
|
|
if (tabs.length === 0 || panels.length === 0) {
|
|
return;
|
|
}
|
|
|
|
var tabNameMap = {
|
|
'shoppro-tab-integration': 'integration',
|
|
'shoppro-tab-statuses': 'statuses',
|
|
'shoppro-tab-settings': 'settings',
|
|
'shoppro-tab-delivery': 'delivery'
|
|
};
|
|
|
|
tabs.forEach(function (tab) {
|
|
tab.addEventListener('click', function () {
|
|
var target = tab.getAttribute('data-tab-target');
|
|
var tabName = tabNameMap[target] || 'integration';
|
|
var url = new URL(window.location.href);
|
|
var currentTab = url.searchParams.get('tab') || 'integration';
|
|
if (tabName === 'integration') {
|
|
url.searchParams.delete('tab');
|
|
} else {
|
|
url.searchParams.set('tab', tabName);
|
|
}
|
|
if (tabName === 'delivery' && currentTab !== 'delivery') {
|
|
window.location.href = url.toString();
|
|
return;
|
|
}
|
|
window.history.replaceState(null, '', url.toString());
|
|
|
|
tabs.forEach(function (node) { node.classList.remove('is-active'); });
|
|
panels.forEach(function (panel) { panel.classList.remove('is-active'); });
|
|
tab.classList.add('is-active');
|
|
var panel = document.querySelector('[data-tab-panel="' + target + '"]');
|
|
if (panel) {
|
|
panel.classList.add('is-active');
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
|
|
(function () {
|
|
var select = document.getElementById('shoppro-integration-select');
|
|
if (!select) {
|
|
return;
|
|
}
|
|
select.addEventListener('change', function () {
|
|
var url = new URL(window.location.href);
|
|
if (select.value) {
|
|
url.searchParams.set('id', select.value);
|
|
} else {
|
|
url.searchParams.delete('id');
|
|
}
|
|
window.location.href = url.toString();
|
|
});
|
|
})();
|
|
|
|
(function () {
|
|
document.querySelectorAll('.dm-carrier-select').forEach(function (carrierSelect) {
|
|
var rowIdx = carrierSelect.getAttribute('data-row');
|
|
var serviceWrap = document.querySelector('.dm-service-wrap[data-row="' + rowIdx + '"]');
|
|
if (!serviceWrap) return;
|
|
|
|
var allegroPanel = serviceWrap.querySelector('.dm-allegro-panel');
|
|
var inpostPanel = serviceWrap.querySelector('.dm-inpost-panel');
|
|
var apaczkaPanel = serviceWrap.querySelector('.dm-apaczka-panel');
|
|
var emptyPanel = serviceWrap.querySelector('.dm-empty-panel');
|
|
var hiddenMethodId = serviceWrap.querySelector('.dm-hidden-method-id');
|
|
var hiddenApaczkaMethodId = serviceWrap.querySelector('.dm-hidden-apaczka-method-id');
|
|
var hiddenCredentialsId = serviceWrap.querySelector('.dm-hidden-credentials-id');
|
|
var hiddenCarrierId = serviceWrap.querySelector('.dm-hidden-carrier-id');
|
|
var hiddenServiceName = serviceWrap.querySelector('.dm-hidden-service-name');
|
|
|
|
function showPanel(carrier) {
|
|
if (allegroPanel) allegroPanel.style.display = carrier === 'allegro' ? '' : 'none';
|
|
if (inpostPanel) inpostPanel.style.display = carrier === 'inpost' ? '' : 'none';
|
|
if (apaczkaPanel) apaczkaPanel.style.display = carrier === 'apaczka' ? '' : 'none';
|
|
if (emptyPanel) emptyPanel.style.display = carrier === '' ? '' : 'none';
|
|
}
|
|
|
|
showPanel(carrierSelect.value);
|
|
|
|
carrierSelect.addEventListener('change', function () {
|
|
var carrier = carrierSelect.value;
|
|
showPanel(carrier);
|
|
if (hiddenMethodId) hiddenMethodId.value = '';
|
|
if (hiddenApaczkaMethodId) hiddenApaczkaMethodId.value = '';
|
|
if (hiddenCredentialsId) hiddenCredentialsId.value = '';
|
|
if (hiddenCarrierId) hiddenCarrierId.value = '';
|
|
if (hiddenServiceName) hiddenServiceName.value = '';
|
|
var allegroInput = allegroPanel ? allegroPanel.querySelector('.dm-search-input') : null;
|
|
if (allegroInput) {
|
|
allegroInput.value = '';
|
|
allegroInput.blur();
|
|
}
|
|
var allegroDropdown = allegroPanel ? allegroPanel.querySelector('.dm-dropdown') : null;
|
|
if (allegroDropdown) {
|
|
allegroDropdown.classList.remove('is-open');
|
|
}
|
|
[inpostPanel, apaczkaPanel].forEach(function (panel) {
|
|
if (!panel) return;
|
|
var inp = panel.querySelector('.dm-search-input');
|
|
if (inp) { inp.value = ''; inp.blur(); }
|
|
var dd = panel.querySelector('.dm-dropdown');
|
|
if (dd) dd.classList.remove('is-open');
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
document.querySelectorAll('.dm-searchable-select').forEach(function (wrapper) {
|
|
var searchInput = wrapper.querySelector('.dm-search-input');
|
|
var dropdown = wrapper.querySelector('.dm-dropdown');
|
|
var serviceWrap = wrapper.closest('.dm-service-wrap');
|
|
if (!searchInput || !dropdown || !serviceWrap) return;
|
|
|
|
var hiddenMethodId = serviceWrap.querySelector('.dm-hidden-method-id');
|
|
var hiddenApaczkaMethodId = serviceWrap.querySelector('.dm-hidden-apaczka-method-id');
|
|
var hiddenCredentialsId = serviceWrap.querySelector('.dm-hidden-credentials-id');
|
|
var hiddenCarrierId = serviceWrap.querySelector('.dm-hidden-carrier-id');
|
|
var hiddenServiceName = serviceWrap.querySelector('.dm-hidden-service-name');
|
|
|
|
var options = dropdown.querySelectorAll('.searchable-select__option');
|
|
wrapper.style.position = 'relative';
|
|
|
|
var provider = wrapper.getAttribute('data-provider') || '';
|
|
var isApaczka = provider === 'apaczka';
|
|
|
|
function selectOption(opt) {
|
|
var val = opt.getAttribute('data-value') || '';
|
|
if (isApaczka) {
|
|
if (hiddenMethodId) hiddenMethodId.value = '';
|
|
if (hiddenApaczkaMethodId) hiddenApaczkaMethodId.value = val;
|
|
if (hiddenCredentialsId) hiddenCredentialsId.value = '';
|
|
} else {
|
|
if (hiddenMethodId) hiddenMethodId.value = val;
|
|
if (hiddenApaczkaMethodId) hiddenApaczkaMethodId.value = '';
|
|
if (hiddenCredentialsId) hiddenCredentialsId.value = opt.getAttribute('data-credentials-id') || '';
|
|
}
|
|
if (hiddenCarrierId) hiddenCarrierId.value = opt.getAttribute('data-carrier-id') || '';
|
|
if (hiddenServiceName) hiddenServiceName.value = opt.getAttribute('data-label') || '';
|
|
searchInput.value = opt.getAttribute('data-label') || '';
|
|
dropdown.classList.remove('is-open');
|
|
options.forEach(function (o) { o.classList.remove('is-selected'); });
|
|
opt.classList.add('is-selected');
|
|
}
|
|
|
|
function filterOptions(query) {
|
|
var q = query.toLowerCase().trim();
|
|
options.forEach(function (opt) {
|
|
var label = (opt.getAttribute('data-label') || '').toLowerCase();
|
|
opt.style.display = (q === '' || label.indexOf(q) !== -1) ? '' : 'none';
|
|
});
|
|
}
|
|
|
|
searchInput.addEventListener('focus', function () {
|
|
filterOptions(searchInput.value);
|
|
dropdown.classList.add('is-open');
|
|
});
|
|
|
|
searchInput.addEventListener('input', function () {
|
|
filterOptions(searchInput.value);
|
|
dropdown.classList.add('is-open');
|
|
});
|
|
|
|
options.forEach(function (opt) {
|
|
opt.addEventListener('mousedown', function (e) {
|
|
e.preventDefault();
|
|
selectOption(opt);
|
|
});
|
|
});
|
|
|
|
searchInput.addEventListener('blur', function () {
|
|
setTimeout(function () { dropdown.classList.remove('is-open'); }, 150);
|
|
});
|
|
|
|
var currentId = wrapper.getAttribute('data-current-id') || '';
|
|
if (currentId !== '') {
|
|
options.forEach(function (opt) {
|
|
if (opt.getAttribute('data-value') === currentId) {
|
|
opt.classList.add('is-selected');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
})();
|
|
</script>
|