Phase 108 complete (v3.2 milestone):
Plan 108-01 — Delivery Status DB & CRUD:
- Tabela delivery_statuses z seedem 11 statusow systemowych
- DeliveryStatusRepository (CRUD + per-request static cache)
- DeliveryStatus::setRepository() — DB fallback dla static final class
- Panel /settings/delivery-statuses (zakladki Statusy + Mapowanie)
- Sidebar przebudowany: Statusy zamowien + Statusy przesylek
Plan 108-02 — Automation Dropdowns z DB + UI Refactor:
- Dropdowny automatyzacji ladowane z DB (warunek shipment_status + akcja update_shipment_status)
- Walidacja przez DeliveryStatus::getAllStatuses()
- Osobna podstrona formularza CRUD (delivery-status-form.php)
- Lista uproszczona: rename Terminal -> Koncowy, usunieta kolumna Typ
- BREAKING: drop backward compat dla starych grupowych kluczy automatyzacji
- Bug fix: path params w DeliveryStatusesController via \$request->input('id')
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
212 lines
8.8 KiB
PHP
212 lines
8.8 KiB
PHP
<?php
|
|
$providersList = is_array($providers ?? null) ? $providers : [];
|
|
$mappingsList = is_array($mappings ?? null) ? $mappings : [];
|
|
$normalizedOptionsList = is_array($normalizedOptions ?? null) ? $normalizedOptions : [];
|
|
$unmappedList = is_array($unmappedRawStatuses ?? null) ? $unmappedRawStatuses : [];
|
|
$currentProvider = (string) ($provider ?? 'inpost');
|
|
$mappingBaseUrl = isset($mappingBaseUrl) ? (string) $mappingBaseUrl : '/settings/delivery-status-mappings';
|
|
?>
|
|
|
|
<?php if ($unmappedList !== []): ?>
|
|
<section class="card mt-16 dsm-unmapped">
|
|
<h2 class="section-title">Niezmapowane statusy wykryte w systemie (<?= count($unmappedList) ?>)</h2>
|
|
<p class="muted mt-8">Statusy odebrane z API przewoźnika <strong><?= $e((string) ($providersList[$currentProvider] ?? $currentProvider)) ?></strong>, dla których nie ma jeszcze mapowania. Przypisz znormalizowany status, aby paczki przestały być oznaczane jako „Nieznany".</p>
|
|
|
|
<form action="/settings/delivery-status-mappings/save-bulk" method="post" class="mt-12">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="provider" value="<?= $e($currentProvider) ?>">
|
|
|
|
<div class="table-wrapper">
|
|
<table class="table table--compact">
|
|
<thead>
|
|
<tr>
|
|
<th>Status surowy</th>
|
|
<th>Liczba paczek</th>
|
|
<th>Ostatnio widziany</th>
|
|
<th>Opis (własny)</th>
|
|
<th>Status znormalizowany</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($unmappedList as $unmapped): ?>
|
|
<?php
|
|
$rawStatus = (string) ($unmapped['raw_status'] ?? '');
|
|
$count = (int) ($unmapped['count'] ?? 0);
|
|
$lastSeen = (string) ($unmapped['last_seen'] ?? '');
|
|
?>
|
|
<tr>
|
|
<td>
|
|
<code class="dsm-raw-status"><?= $e($rawStatus) ?></code>
|
|
<input type="hidden" name="raw_status[]" value="<?= $e($rawStatus) ?>">
|
|
</td>
|
|
<td><?= $count ?></td>
|
|
<td><?= $e($lastSeen) ?></td>
|
|
<td>
|
|
<input type="text" name="description[]" class="form-control form-control--sm"
|
|
value="<?= $e($rawStatus) ?>" maxlength="255">
|
|
</td>
|
|
<td>
|
|
<select name="normalized_status[]" class="form-control form-control--sm" required>
|
|
<?php foreach ($normalizedOptionsList as $optValue => $optLabel): ?>
|
|
<option value="<?= $e($optValue) ?>"<?= $optValue === 'unknown' ? ' selected' : '' ?>>
|
|
<?= $e($optLabel) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="form-actions mt-12">
|
|
<button type="submit" class="btn btn--primary">Dodaj do mapowania</button>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
<?php endif; ?>
|
|
|
|
<section class="card mt-16">
|
|
<nav class="content-tabs-nav" aria-label="Wybierz przewoźnika">
|
|
<?php foreach ($providersList as $provKey => $provLabel): ?>
|
|
<?php
|
|
$mappingProviderUrl = $mappingBaseUrl . (str_contains($mappingBaseUrl, '?') ? '&' : '?') . 'provider=' . rawurlencode($provKey);
|
|
?>
|
|
<a class="content-tab-btn<?= $currentProvider === $provKey ? ' is-active' : '' ?>"
|
|
href="<?= $e($mappingProviderUrl) ?>">
|
|
<?= $e($provLabel) ?>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</nav>
|
|
|
|
<?php if ($mappingsList === []): ?>
|
|
<p class="muted mt-16">Brak mapowań dla tego przewoźnika.</p>
|
|
<?php else: ?>
|
|
<form id="dsm-bulk-form" action="/settings/delivery-status-mappings/save-bulk" method="post" class="mt-16">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="provider" value="<?= $e($currentProvider) ?>">
|
|
|
|
<div class="table-wrapper">
|
|
<table class="table table--compact">
|
|
<thead>
|
|
<tr>
|
|
<th>Status surowy</th>
|
|
<th>Opis</th>
|
|
<th>Status znormalizowany</th>
|
|
<th>Akcje</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($mappingsList as $mapping): ?>
|
|
<?php
|
|
$rawStatus = (string) ($mapping['raw_status'] ?? '');
|
|
$desc = (string) ($mapping['description'] ?? '');
|
|
$normalized = (string) ($mapping['normalized_status'] ?? '');
|
|
$isCustom = !empty($mapping['is_custom']);
|
|
?>
|
|
<tr class="<?= $isCustom ? 'dsm-row--custom' : '' ?>">
|
|
<td>
|
|
<code class="dsm-raw-status"><?= $e($rawStatus) ?></code>
|
|
<input type="hidden" name="raw_status[]" value="<?= $e($rawStatus) ?>">
|
|
</td>
|
|
<td>
|
|
<input type="text" name="description[]" class="form-control form-control--sm"
|
|
value="<?= $e($desc) ?>" maxlength="255">
|
|
</td>
|
|
<td>
|
|
<select name="normalized_status[]" class="form-control form-control--sm">
|
|
<?php foreach ($normalizedOptionsList as $optValue => $optLabel): ?>
|
|
<option value="<?= $e($optValue) ?>"<?= $optValue === $normalized ? ' selected' : '' ?>>
|
|
<?= $e($optLabel) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</td>
|
|
<td>
|
|
<?php if ($isCustom): ?>
|
|
<button type="button" class="btn btn--danger btn--sm js-dsm-reset"
|
|
data-raw-status="<?= $e($rawStatus) ?>"
|
|
data-confirm-msg="Przywrócić domyślne mapowanie dla "<?= $e($rawStatus) ?>"?">Resetuj</button>
|
|
<?php else: ?>
|
|
<span class="muted">domyślne</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="form-actions mt-16">
|
|
<button type="submit" class="btn btn--primary">Zapisz wszystkie</button>
|
|
<button type="button" class="btn btn--danger" id="js-dsm-reset-all">Resetuj wszystkie</button>
|
|
</div>
|
|
</form>
|
|
|
|
<form id="dsm-reset-all-form" action="/settings/delivery-status-mappings/reset-all" method="post" style="display:none;">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="provider" value="<?= $e($currentProvider) ?>">
|
|
</form>
|
|
|
|
<form id="dsm-reset-form" action="/settings/delivery-status-mappings/reset" method="post" style="display:none;">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<input type="hidden" name="provider" value="<?= $e($currentProvider) ?>">
|
|
<input type="hidden" name="raw_status" id="dsm-reset-raw-status" value="">
|
|
</form>
|
|
<?php endif; ?>
|
|
</section>
|
|
|
|
<script>
|
|
(function() {
|
|
var resetForm = document.getElementById('dsm-reset-form');
|
|
var resetInput = document.getElementById('dsm-reset-raw-status');
|
|
if (!resetForm || !resetInput) return;
|
|
|
|
var resetAllBtn = document.getElementById('js-dsm-reset-all');
|
|
var resetAllForm = document.getElementById('dsm-reset-all-form');
|
|
if (resetAllBtn && resetAllForm) {
|
|
resetAllBtn.addEventListener('click', function() {
|
|
if (window.OrderProAlerts && typeof window.OrderProAlerts.confirm === 'function') {
|
|
window.OrderProAlerts.confirm({
|
|
title: 'Resetuj wszystkie mapowania',
|
|
message: 'Przywrócić wszystkie mapowania do domyślnych dla tego przewoźnika?',
|
|
confirmLabel: 'Resetuj wszystkie',
|
|
cancelLabel: 'Anuluj',
|
|
danger: true
|
|
}).then(function(accepted) {
|
|
if (!accepted) return;
|
|
resetAllForm.submit();
|
|
});
|
|
} else {
|
|
resetAllForm.submit();
|
|
}
|
|
});
|
|
}
|
|
|
|
document.querySelectorAll('.js-dsm-reset').forEach(function(btn) {
|
|
btn.addEventListener('click', function() {
|
|
var rawStatus = btn.getAttribute('data-raw-status') || '';
|
|
var message = btn.getAttribute('data-confirm-msg') || 'Przywrócić domyślne?';
|
|
|
|
if (window.OrderProAlerts && typeof window.OrderProAlerts.confirm === 'function') {
|
|
window.OrderProAlerts.confirm({
|
|
title: 'Resetuj mapowanie',
|
|
message: message,
|
|
confirmLabel: 'Resetuj',
|
|
cancelLabel: 'Anuluj',
|
|
danger: true
|
|
}).then(function(accepted) {
|
|
if (!accepted) return;
|
|
resetInput.value = rawStatus;
|
|
resetForm.submit();
|
|
});
|
|
} else {
|
|
resetInput.value = rawStatus;
|
|
resetForm.submit();
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
</script>
|