- Kolorowe badge'e statusow dostawy w tabelach paczek (show.php + prepare.php) - Link sledzenia z carrier detection (InPost, Apaczka, Orlen, Allegro, Google fallback) - Sekcja Status dostawy w boksie Platnosc i wysylka - Ustawienie interwalu trackingu crona (5-120 min) w zakladce Ustawienia - Tekstowe mapowania statusow Apaczka API (NEW, CONFIRMED, etc.) - Fix: use-statements ApaczkaShipmentService (pre-existing bug) - Fix: pickup date normalization (next day po 16:00) - Fix: przycisk Pobierz etykiete (POST zamiast link do prepare) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1217 lines
50 KiB
PHP
1217 lines
50 KiB
PHP
<?php
|
|
$orderRow = is_array($order ?? null) ? $order : [];
|
|
$itemsList = is_array($items ?? null) ? $items : [];
|
|
$receiver = is_array($receiverAddr ?? null) ? $receiverAddr : [];
|
|
$prefs = is_array($preferences ?? null) ? $preferences : [];
|
|
$comp = is_array($company ?? null) ? $company : [];
|
|
$services = is_array($deliveryServices ?? null) ? $deliveryServices : [];
|
|
$apaczkaSvcList = is_array($apaczkaServices ?? null) ? $apaczkaServices : [];
|
|
$packages = is_array($existingPackages ?? null) ? $existingPackages : [];
|
|
$pendingPrintIds = is_array($pendingPrintPackageIds ?? null) ? $pendingPrintPackageIds : [];
|
|
$servicesError = (string) ($deliveryServicesError ?? '');
|
|
$flashSuccessMsg = (string) ($flashSuccess ?? '');
|
|
$flashErrorMsg = (string) ($flashError ?? '');
|
|
$deliveryMappingDiagnostic = trim((string) ($deliveryMappingDiagnostic ?? ''));
|
|
|
|
$mapping = is_array($deliveryMapping ?? null) ? $deliveryMapping : [];
|
|
$mappedMethodId = trim((string) ($mapping['provider_service_id'] ?? ''));
|
|
$mappedCredentialsId = trim((string) ($mapping['provider_account_id'] ?? ''));
|
|
$mappedCarrierId = trim((string) ($mapping['provider_carrier_id'] ?? ''));
|
|
$mappedProvider = trim((string) ($mapping['provider'] ?? ''));
|
|
$mappedServiceName = trim((string) ($mapping['provider_service_name'] ?? ''));
|
|
$mappedCarrier = $mappedProvider === 'apaczka' ? 'apaczka' : 'allegro';
|
|
if ($mappedCarrier !== 'apaczka' && stripos($mappedCarrierId, 'inpost') !== false) {
|
|
$mappedCarrier = 'inpost';
|
|
}
|
|
$deliveryMethodId = '';
|
|
if ($mappedCarrier === 'apaczka' && $mappedMethodId !== '') {
|
|
$deliveryMethodId = $mappedMethodId;
|
|
} elseif (($mappedCarrier === 'allegro' || $mappedCarrier === 'inpost') && $mappedMethodId !== '') {
|
|
$deliveryMethodId = $mappedMethodId;
|
|
} elseif ($mappedCarrier !== 'inpost') {
|
|
$deliveryMethodId = trim((string) ($prefs['delivery_method_id'] ?? ($orderRow['external_carrier_account_id'] ?? '')));
|
|
}
|
|
$deliveryMethodName = trim((string) ($orderRow['external_carrier_id'] ?? ''));
|
|
$inpostSvcList = is_array($inpostServices ?? null) ? $inpostServices : [];
|
|
$preselectedCarrier = $mappedCarrier !== '' ? $mappedCarrier : ($mappedMethodId !== '' ? 'allegro' : '');
|
|
$pointId = trim((string) ($receiver['parcel_external_id'] ?? ''));
|
|
$pointName = trim((string) ($receiver['parcel_name'] ?? ''));
|
|
$totalWithTax = (float) ($orderRow['total_with_tax'] ?? 0);
|
|
$currency = strtoupper(trim((string) ($orderRow['currency'] ?? 'PLN')));
|
|
$isCod = strtoupper(trim((string) ($orderRow['external_payment_type_id'] ?? ''))) === 'CASH_ON_DELIVERY';
|
|
$defaultCodAmount = $isCod ? number_format($totalWithTax, 2, '.', '') : '0';
|
|
?>
|
|
|
|
<section class="card">
|
|
<div class="order-details-head">
|
|
<div>
|
|
<a href="/orders/<?= $e((string) ($orderId ?? 0)) ?>" class="order-back-link">← Powrot do zamowienia</a>
|
|
<h2 class="section-title mt-12">Przygotuj przesylke #<?= $e((string) ($orderId ?? 0)) ?></h2>
|
|
<div class="order-details-sub mt-4">
|
|
<span><?= $e(ucfirst((string) ($orderRow['source'] ?? ''))) ?> <?= $e((string) ($orderRow['external_order_id'] ?? '')) ?></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($flashSuccessMsg !== ''): ?>
|
|
<div class="flash flash--success mt-12"><?= $e($flashSuccessMsg) ?></div>
|
|
<?php endif; ?>
|
|
<?php if ($flashErrorMsg !== ''): ?>
|
|
<div class="flash flash--error mt-12"><?= $e($flashErrorMsg) ?></div>
|
|
<?php endif; ?>
|
|
</section>
|
|
|
|
<section class="shipment-presets" id="shipment-presets">
|
|
<button type="button" class="shipment-presets__add" id="preset-add-btn">+ Dodaj przycisk dostawy</button>
|
|
</section>
|
|
|
|
<div class="preset-modal" id="preset-modal" style="display:none">
|
|
<div class="preset-modal__content">
|
|
<h3>Nowy przycisk dostawy</h3>
|
|
<label class="form-field mt-12">
|
|
<span class="field-label">Nazwa</span>
|
|
<input class="form-control" type="text" id="preset-name-input" maxlength="100" placeholder="np. InPost Paczkomat Standard">
|
|
</label>
|
|
<div class="form-field mt-12">
|
|
<span class="field-label">Kolor</span>
|
|
<div class="preset-modal__colors" id="preset-color-picker"></div>
|
|
</div>
|
|
<div class="form-actions mt-16">
|
|
<button type="button" class="btn btn--primary" id="preset-save-btn">Zapisz</button>
|
|
<button type="button" class="btn btn--secondary" id="preset-cancel-btn">Anuluj</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post" action="/orders/<?= $e((string) ($orderId ?? 0)) ?>/shipment/create" novalidate>
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
|
|
<div class="shipment-grid mt-16">
|
|
<section class="card">
|
|
<h3 class="section-title">Przesylka</h3>
|
|
|
|
<?php if ($servicesError !== ''): ?>
|
|
<div class="flash flash--error mt-12"><?= $e($servicesError) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="form-field mt-12">
|
|
<span class="field-label">Przewoznik</span>
|
|
<select class="form-control" id="shipment-carrier-select">
|
|
<option value="">-- Wybierz --</option>
|
|
<option value="allegro"<?= $preselectedCarrier === 'allegro' ? ' selected' : '' ?>>Allegro</option>
|
|
<option value="inpost"<?= $preselectedCarrier === 'inpost' ? ' selected' : '' ?>>InPost</option>
|
|
<option value="apaczka"<?= $preselectedCarrier === 'apaczka' ? ' selected' : '' ?>>Apaczka</option>
|
|
</select>
|
|
<?php if ($deliveryMethodName !== ''): ?>
|
|
<div class="muted mt-4" style="font-size:12px">Metoda z zamowienia: <strong><?= $e($deliveryMethodName) ?></strong><?php if ($mappedServiceName !== ''): ?> → <?= $e($mappedCarrier === 'inpost' ? 'InPost' : ($mappedCarrier === 'apaczka' ? 'Apaczka' : 'Allegro')) ?>: <?= $e($mappedServiceName) ?><?php endif; ?></div>
|
|
<?php endif; ?>
|
|
<?php if ($deliveryMappingDiagnostic !== ''): ?>
|
|
<div class="flash flash--error mt-8"><?= $e($deliveryMappingDiagnostic) ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="form-field mt-12">
|
|
<span class="field-label">Usluga dostawy</span>
|
|
<input type="hidden" name="delivery_method_id" id="shipment-delivery-service" value="" required>
|
|
|
|
<div id="shipment-allegro-panel" style="<?= $preselectedCarrier !== 'allegro' ? 'display:none' : '' ?>">
|
|
<?php if ($servicesError !== ''): ?>
|
|
<div class="flash flash--error mt-4"><?= $e($servicesError) ?></div>
|
|
<?php endif; ?>
|
|
<div class="searchable-select" id="shipment-service-wrapper" data-match-id="<?= $e($deliveryMethodId) ?>">
|
|
<input type="text" class="form-control" id="shipment-service-search" placeholder="Szukaj uslugi dostawy Allegro..." autocomplete="off">
|
|
<div class="searchable-select__dropdown" id="shipment-service-dropdown">
|
|
<?php foreach ($services as $svc): ?>
|
|
<?php
|
|
$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'] ?? ''));
|
|
?>
|
|
<div class="searchable-select__option"
|
|
data-value="<?= $e($svcMethodId) ?>"
|
|
data-credentials-id="<?= $e($svcCredentialsId) ?>"
|
|
data-carrier-id="<?= $e($svcCarrierId) ?>"
|
|
data-owner="<?= $e($svcOwner) ?>"
|
|
data-label="<?= $e($svcName) ?> (<?= $e($svcOwner) ?>)"
|
|
><?= $e($svcName) ?> <span class="muted">(<?= $e($svcOwner) ?>)</span></div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="shipment-inpost-panel" style="<?= $preselectedCarrier !== 'inpost' ? 'display:none' : '' ?>">
|
|
<?php if ($inpostSvcList === []): ?>
|
|
<div class="muted">Brak uslug InPost (sprawdz polaczenie z Allegro).</div>
|
|
<?php else: ?>
|
|
<select class="form-control" id="shipment-inpost-select">
|
|
<option value="">-- Wybierz usluge InPost --</option>
|
|
<?php foreach ($inpostSvcList as $inSvc): ?>
|
|
<?php
|
|
$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'] ?? ''));
|
|
$inSvcSelected = $mappedCarrier === 'inpost' && $mappedMethodId === $inSvcMethodId;
|
|
?>
|
|
<option
|
|
value="<?= $e($inSvcMethodId) ?>"
|
|
data-credentials-id="<?= $e($inSvcCredentialsId) ?>"
|
|
data-carrier-id="<?= $e($inSvcCarrierId) ?>"
|
|
<?= $inSvcSelected ? 'selected' : '' ?>>
|
|
<?= $e($inSvcName) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div id="shipment-apaczka-panel" style="<?= $preselectedCarrier !== 'apaczka' ? 'display:none' : '' ?>">
|
|
<?php if ($apaczkaSvcList === []): ?>
|
|
<div class="muted">Brak uslug Apaczka (sprawdz konfiguracje App ID/App Secret).</div>
|
|
<?php else: ?>
|
|
<select class="form-control" id="shipment-apaczka-select">
|
|
<option value="">-- Wybierz usluge Apaczka --</option>
|
|
<?php foreach ($apaczkaSvcList as $aSvc): ?>
|
|
<?php
|
|
if (!is_array($aSvc)) {
|
|
continue;
|
|
}
|
|
$aSvcId = trim((string) ($aSvc['service_id'] ?? $aSvc['id'] ?? ''));
|
|
$aSvcName = trim((string) ($aSvc['name'] ?? ''));
|
|
$aSvcCarrierCode = trim((string) ($aSvc['carrier_code'] ?? ''));
|
|
$aSvcSelected = $mappedCarrier === 'apaczka' && $mappedMethodId === $aSvcId;
|
|
?>
|
|
<option
|
|
value="<?= $e($aSvcId) ?>"
|
|
data-carrier-id="<?= $e($aSvcCarrierCode) ?>"
|
|
<?= $aSvcSelected ? 'selected' : '' ?>>
|
|
<?= $e($aSvcName !== '' ? $aSvcName : ('ID ' . $aSvcId)) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div id="shipment-empty-panel" class="muted" style="<?= $preselectedCarrier !== '' ? 'display:none' : '' ?>">Wybierz przewoznika</div>
|
|
</div>
|
|
|
|
<input type="hidden" name="credentials_id" id="shipment-credentials-id" value="">
|
|
<input type="hidden" name="carrier_id" id="shipment-carrier-id" value="">
|
|
<input type="hidden" name="provider_code" id="shipment-provider-code" value="<?= $e($preselectedCarrier === 'apaczka' ? 'apaczka' : 'allegro_wza') ?>">
|
|
|
|
<label class="form-field">
|
|
<span class="field-label">Typ paczki</span>
|
|
<select class="form-control" name="package_type">
|
|
<option value="PACKAGE" selected>Paczka</option>
|
|
<option value="DOX">Dokument</option>
|
|
<option value="PALLET">Paleta</option>
|
|
</select>
|
|
</label>
|
|
|
|
<div class="form-grid-4">
|
|
<label class="form-field">
|
|
<span class="field-label">Dlugosc (cm)</span>
|
|
<input class="form-control" type="number" name="length_cm" step="0.1" min="0.1" value="<?= $e((string) ($comp['default_package_length_cm'] ?? '25')) ?>">
|
|
</label>
|
|
<label class="form-field">
|
|
<span class="field-label">Szerokosc (cm)</span>
|
|
<input class="form-control" type="number" name="width_cm" step="0.1" min="0.1" value="<?= $e((string) ($comp['default_package_width_cm'] ?? '20')) ?>">
|
|
</label>
|
|
<label class="form-field">
|
|
<span class="field-label">Wysokosc (cm)</span>
|
|
<input class="form-control" type="number" name="height_cm" step="0.1" min="0.1" value="<?= $e((string) ($comp['default_package_height_cm'] ?? '8')) ?>">
|
|
</label>
|
|
<label class="form-field">
|
|
<span class="field-label">Waga (kg)</span>
|
|
<input class="form-control" type="number" name="weight_kg" step="0.001" min="0.001" value="<?= $e((string) ($comp['default_package_weight_kg'] ?? '1')) ?>">
|
|
</label>
|
|
</div>
|
|
|
|
<div class="form-grid-2">
|
|
<label class="form-field">
|
|
<span class="field-label">Ubezpieczenie (<?= $e($currency) ?>)</span>
|
|
<input class="form-control" type="number" name="insurance_amount" step="0.01" min="0" value="<?= $e(number_format($totalWithTax, 2, '.', '')) ?>">
|
|
<input type="hidden" name="insurance_currency" value="<?= $e($currency) ?>">
|
|
</label>
|
|
<label class="form-field">
|
|
<span class="field-label">Format etykiety</span>
|
|
<select class="form-control" name="label_format">
|
|
<option value="PDF"<?= ((string) ($comp['default_label_format'] ?? 'PDF')) === 'PDF' ? ' selected' : '' ?>>PDF</option>
|
|
<option value="ZPL"<?= ((string) ($comp['default_label_format'] ?? 'PDF')) === 'ZPL' ? ' selected' : '' ?>>ZPL</option>
|
|
</select>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="form-grid-2">
|
|
<label class="form-field">
|
|
<span class="field-label">Pobranie (<?= $e($currency) ?>)<?= $isCod ? ' <span class="order-tag is-cod" style="font-size:0.7rem;vertical-align:middle">ZA POBRANIEM</span>' : '' ?></span>
|
|
<input class="form-control" type="number" name="cod_amount" step="0.01" min="0" value="<?= $e($defaultCodAmount) ?>">
|
|
<input type="hidden" name="cod_currency" value="<?= $e($currency) ?>">
|
|
</label>
|
|
</div>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label">Punkt nadania (opcjonalnie)</span>
|
|
<input class="form-control" type="text" name="sender_point_id" maxlength="64" placeholder="np. KRA010">
|
|
</label>
|
|
</section>
|
|
|
|
<section class="card">
|
|
<h3 class="section-title">Adres odbiorcy</h3>
|
|
|
|
<label class="form-field mt-12">
|
|
<span class="field-label">Imie i nazwisko</span>
|
|
<input class="form-control" type="text" name="receiver_name" maxlength="200" value="<?= $e((string) ($receiver['name'] ?? '')) ?>" required>
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label">Firma (opcjonalnie)</span>
|
|
<input class="form-control" type="text" name="receiver_company" maxlength="200" value="<?= $e((string) ($receiver['company_name'] ?? '')) ?>">
|
|
</label>
|
|
|
|
<label class="form-field">
|
|
<span class="field-label">Ulica</span>
|
|
<input class="form-control" type="text" name="receiver_street" maxlength="200" value="<?= $e((string) ($receiver['street_name'] ?? '')) ?>" required>
|
|
</label>
|
|
|
|
<div class="form-grid-3">
|
|
<label class="form-field">
|
|
<span class="field-label">Kod pocztowy</span>
|
|
<input class="form-control" type="text" name="receiver_postal_code" maxlength="16" value="<?= $e((string) ($receiver['zip_code'] ?? '')) ?>" required>
|
|
</label>
|
|
<label class="form-field">
|
|
<span class="field-label">Miasto</span>
|
|
<input class="form-control" type="text" name="receiver_city" maxlength="128" value="<?= $e((string) ($receiver['city'] ?? '')) ?>" required>
|
|
</label>
|
|
<label class="form-field">
|
|
<span class="field-label">Kraj</span>
|
|
<input class="form-control" type="text" name="receiver_country_code" maxlength="2" value="<?= $e((string) ($receiver['country'] ?? 'PL')) ?>" required>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="form-grid-2">
|
|
<label class="form-field">
|
|
<span class="field-label">Telefon</span>
|
|
<input class="form-control" type="tel" name="receiver_phone" maxlength="64" value="<?= $e((string) ($receiver['phone'] ?? '')) ?>" required>
|
|
</label>
|
|
<label class="form-field">
|
|
<span class="field-label">E-mail</span>
|
|
<input class="form-control" type="email" name="receiver_email" maxlength="128" value="<?= $e((string) ($receiver['email'] ?? '')) ?>" required>
|
|
</label>
|
|
</div>
|
|
|
|
<?php if ($pointId !== ''): ?>
|
|
<label class="form-field">
|
|
<span class="field-label">Punkt odbioru<?= $pointName !== '' ? ' (' . $e($pointName) . ')' : '' ?></span>
|
|
<input class="form-control" type="text" name="receiver_point_id" maxlength="64" value="<?= $e($pointId) ?>">
|
|
</label>
|
|
<?php else: ?>
|
|
<label class="form-field">
|
|
<span class="field-label">Punkt odbioru (opcjonalnie)</span>
|
|
<input class="form-control" type="text" name="receiver_point_id" maxlength="64" value="">
|
|
</label>
|
|
<?php endif; ?>
|
|
</section>
|
|
</div>
|
|
|
|
<section class="card mt-16">
|
|
<h3 class="section-title">Pozycje zamowienia (<?= $e((string) count($itemsList)) ?>)</h3>
|
|
<div class="table-wrap mt-12">
|
|
<table class="table table--details">
|
|
<thead>
|
|
<tr><th>Lp.</th><th>Nazwa</th><th>Ilosc</th><th>Cena</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($itemsList as $idx => $item): ?>
|
|
<tr>
|
|
<td><?= $e((string) ($idx + 1)) ?></td>
|
|
<td><?= $e((string) ($item['original_name'] ?? '')) ?></td>
|
|
<td><?= $e((string) ($item['quantity'] ?? 0)) ?></td>
|
|
<td><?= $e($item['original_price_with_tax'] !== null ? number_format((float) $item['original_price_with_tax'], 2, '.', ' ') : '-') ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="form-actions mt-16">
|
|
<button type="submit" class="btn btn--primary">Utworz przesylke</button>
|
|
<a href="/orders/<?= $e((string) ($orderId ?? 0)) ?>" class="btn btn--secondary">Anuluj</a>
|
|
</div>
|
|
</section>
|
|
</form>
|
|
|
|
<?php if ($packages !== []): ?>
|
|
<section class="card mt-16">
|
|
<h3 class="section-title">Utworzone przesylki</h3>
|
|
<div class="table-wrap mt-12">
|
|
<table class="table table--details">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Status</th>
|
|
<th>Status dostawy</th>
|
|
<th>Nr sledzenia</th>
|
|
<th>Przewoznik</th>
|
|
<th>Etykieta</th>
|
|
<th>Utworzono</th>
|
|
<th>Akcje</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($packages as $pkg): ?>
|
|
<?php
|
|
$pkgId = (int) ($pkg['id'] ?? 0);
|
|
$pkgStatus = (string) ($pkg['status'] ?? 'draft');
|
|
$pkgTracking = trim((string) ($pkg['tracking_number'] ?? ''));
|
|
$pkgCarrier = trim((string) ($pkg['carrier_id'] ?? ''));
|
|
$pkgLabelPath = trim((string) ($pkg['label_path'] ?? ''));
|
|
$pkgShipmentId = trim((string) ($pkg['shipment_id'] ?? ''));
|
|
$pkgError = trim((string) ($pkg['error_message'] ?? ''));
|
|
?>
|
|
<tr>
|
|
<td><?= $e((string) $pkgId) ?></td>
|
|
<td>
|
|
<span class="order-tag <?= $pkgStatus === 'label_ready' || $pkgStatus === 'created' ? 'is-success' : ($pkgStatus === 'error' ? 'is-danger' : 'is-warn') ?>">
|
|
<?= $e($pkgStatus) ?>
|
|
</span>
|
|
<?php if ($pkgError !== ''): ?>
|
|
<div class="muted mt-4" style="font-size:0.75rem"><?= $e($pkgError) ?></div>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<?php
|
|
$pkgProvider = trim((string) ($pkg['provider'] ?? ''));
|
|
$pkgDeliveryStatus = (string) ($pkg['delivery_status'] ?? 'unknown');
|
|
$pkgDeliveryRaw = trim((string) ($pkg['delivery_status_raw'] ?? ''));
|
|
$pkgDeliveryLabel = \App\Modules\Shipments\DeliveryStatus::label($pkgDeliveryStatus);
|
|
$pkgDeliveryDesc = $pkgDeliveryRaw !== '' ? \App\Modules\Shipments\DeliveryStatus::description($pkgProvider, $pkgDeliveryRaw) : '';
|
|
$pkgDeliveryTitle = $pkgDeliveryRaw !== '' ? ($pkgDeliveryRaw . ' — ' . $pkgDeliveryDesc) : '';
|
|
?>
|
|
<span class="delivery-badge delivery-badge--<?= $e($pkgDeliveryStatus) ?>" title="<?= $e($pkgDeliveryTitle) ?>"><?= $e($pkgDeliveryLabel) ?></span>
|
|
</td>
|
|
<td style="white-space:nowrap">
|
|
<?= $e($pkgTracking !== '' ? $pkgTracking : '-') ?><?php
|
|
$pkgTrackUrl = \App\Modules\Shipments\DeliveryStatus::trackingUrl($pkgProvider, $pkgTracking, trim((string) ($pkg['carrier_id'] ?? '')));
|
|
if ($pkgTrackUrl !== null): ?> <a href="<?= $e($pkgTrackUrl) ?>" target="_blank" class="tracking-link" title="Sledz przesylke">🔗</a><?php endif; ?>
|
|
</td>
|
|
<td><?= $e($pkgCarrier !== '' ? $pkgCarrier : '-') ?></td>
|
|
<td>
|
|
<?php if ($pkgLabelPath !== ''): ?>
|
|
<?php if ($pkgStatus === 'error'): ?>
|
|
-
|
|
<?php else: ?>
|
|
<form method="post" action="/orders/<?= $e((string) ($orderId ?? 0)) ?>/shipment/<?= $e((string) $pkgId) ?>/label" style="display:inline">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<button type="submit" class="btn btn--sm btn--secondary">Pobierz</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
<?php elseif ($pkgShipmentId !== '' && $pkgStatus === 'created'): ?>
|
|
<span class="muted">Generowanie etykiety...</span>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
<?php if (in_array($pkgStatus, ['label_ready', 'created'], true)): ?>
|
|
<?php if (in_array($pkgId, $pendingPrintIds, true)): ?>
|
|
<button type="button" class="btn btn--sm btn--danger" disabled style="white-space:nowrap">W kolejce</button>
|
|
<?php else: ?>
|
|
<button type="button"
|
|
class="btn btn--sm btn--secondary btn-print-label"
|
|
data-package-id="<?= $e((string) $pkgId) ?>"
|
|
data-order-id="<?= $e((string) ($orderId ?? 0)) ?>"
|
|
title="Wyslij do drukarki">Drukuj</button>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap"><?= $e((string) ($pkg['created_at'] ?? '')) ?></td>
|
|
<td>
|
|
<?php
|
|
$shouldCheckStatus = $pkgStatus === 'pending' || ($pkgStatus === 'created' && $pkgLabelPath === '');
|
|
?>
|
|
<?php if ($shouldCheckStatus): ?>
|
|
<button type="button"
|
|
class="btn btn--sm btn--secondary"
|
|
data-check-status="<?= $e((string) $pkgId) ?>"
|
|
data-order-id="<?= $e((string) ($orderId ?? 0)) ?>"
|
|
data-package-status="<?= $e($pkgStatus) ?>"
|
|
data-auto-check="1">Sprawdz status</button>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
<?php endif; ?>
|
|
|
|
<script>
|
|
(function () {
|
|
function enhanceSelect(selectEl) {
|
|
if (!selectEl || selectEl.dataset.enhanced) return;
|
|
selectEl.dataset.enhanced = '1';
|
|
|
|
var parent = selectEl.parentNode;
|
|
var container = document.createElement('div');
|
|
container.className = 'searchable-select';
|
|
parent.insertBefore(container, selectEl);
|
|
container.appendChild(selectEl);
|
|
selectEl.style.display = 'none';
|
|
|
|
var trigger = document.createElement('div');
|
|
trigger.className = 'searchable-select__trigger form-control';
|
|
container.appendChild(trigger);
|
|
|
|
var dd = document.createElement('div');
|
|
dd.className = 'searchable-select__dropdown';
|
|
container.appendChild(dd);
|
|
|
|
var search = document.createElement('input');
|
|
search.type = 'text';
|
|
search.className = 'searchable-select__search form-control';
|
|
search.placeholder = 'Szukaj...';
|
|
search.autocomplete = 'off';
|
|
dd.appendChild(search);
|
|
|
|
var optEls = [];
|
|
Array.from(selectEl.options).forEach(function (opt) {
|
|
var div = document.createElement('div');
|
|
div.className = 'searchable-select__option';
|
|
div.setAttribute('data-value', opt.value);
|
|
div.textContent = opt.textContent.trim();
|
|
if (opt.selected) div.classList.add('is-selected');
|
|
dd.appendChild(div);
|
|
optEls.push(div);
|
|
});
|
|
|
|
function syncTrigger() {
|
|
var opt = selectEl.options[selectEl.selectedIndex];
|
|
var text = opt ? opt.textContent.trim() : '';
|
|
trigger.textContent = text;
|
|
trigger.classList.toggle('searchable-select__trigger--placeholder', !selectEl.value);
|
|
optEls.forEach(function (d) {
|
|
d.classList.toggle('is-selected', d.getAttribute('data-value') === selectEl.value);
|
|
});
|
|
}
|
|
syncTrigger();
|
|
|
|
var isOpen = false;
|
|
|
|
function open() {
|
|
dd.classList.add('is-open');
|
|
isOpen = true;
|
|
search.value = '';
|
|
filterOpts('');
|
|
setTimeout(function () { search.focus(); }, 0);
|
|
}
|
|
|
|
function close() {
|
|
dd.classList.remove('is-open');
|
|
isOpen = false;
|
|
}
|
|
|
|
function pick(div) {
|
|
selectEl.value = div.getAttribute('data-value');
|
|
syncTrigger();
|
|
close();
|
|
selectEl.dispatchEvent(new Event('change', { bubbles: true }));
|
|
}
|
|
|
|
function filterOpts(q) {
|
|
q = q.toLowerCase().trim();
|
|
optEls.forEach(function (d) {
|
|
d.style.display = q === '' || d.textContent.toLowerCase().indexOf(q) !== -1 ? '' : 'none';
|
|
});
|
|
}
|
|
|
|
trigger.addEventListener('click', function (e) {
|
|
e.stopPropagation();
|
|
isOpen ? close() : open();
|
|
});
|
|
|
|
search.addEventListener('input', function () {
|
|
filterOpts(search.value);
|
|
});
|
|
|
|
optEls.forEach(function (d) {
|
|
d.addEventListener('mousedown', function (e) {
|
|
e.preventDefault();
|
|
pick(d);
|
|
});
|
|
});
|
|
|
|
search.addEventListener('blur', function () {
|
|
setTimeout(close, 150);
|
|
});
|
|
|
|
search.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape') close();
|
|
});
|
|
|
|
document.addEventListener('click', function (e) {
|
|
if (isOpen && !container.contains(e.target)) close();
|
|
});
|
|
|
|
selectEl._syncTrigger = syncTrigger;
|
|
}
|
|
|
|
var carrierSelect = document.getElementById('shipment-carrier-select');
|
|
var inpostSelect = document.getElementById('shipment-inpost-select');
|
|
var apaczkaSelect = document.getElementById('shipment-apaczka-select');
|
|
|
|
document.querySelectorAll('form select.form-control').forEach(function (sel) {
|
|
enhanceSelect(sel);
|
|
});
|
|
|
|
var allegroPanel = document.getElementById('shipment-allegro-panel');
|
|
var inpostPanel = document.getElementById('shipment-inpost-panel');
|
|
var apaczkaPanel = document.getElementById('shipment-apaczka-panel');
|
|
var emptyPanel = document.getElementById('shipment-empty-panel');
|
|
|
|
var wrapper = document.getElementById('shipment-service-wrapper');
|
|
var hiddenInput = document.getElementById('shipment-delivery-service');
|
|
var searchInput = document.getElementById('shipment-service-search');
|
|
var dropdown = document.getElementById('shipment-service-dropdown');
|
|
var credentialsInput = document.getElementById('shipment-credentials-id');
|
|
var carrierInput = document.getElementById('shipment-carrier-id');
|
|
var providerInput = document.getElementById('shipment-provider-code');
|
|
|
|
if (!carrierSelect || !hiddenInput) return;
|
|
|
|
var allegroOpts = dropdown ? dropdown.querySelectorAll('.searchable-select__option') : [];
|
|
|
|
function clearHiddenFields() {
|
|
hiddenInput.value = '';
|
|
credentialsInput.value = '';
|
|
carrierInput.value = '';
|
|
}
|
|
|
|
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';
|
|
if (providerInput) providerInput.value = carrier === 'apaczka' ? 'apaczka' : 'allegro_wza';
|
|
}
|
|
|
|
carrierSelect.addEventListener('change', function () {
|
|
clearHiddenFields();
|
|
if (searchInput) searchInput.value = '';
|
|
if (inpostSelect) {
|
|
inpostSelect.selectedIndex = 0;
|
|
if (inpostSelect._syncTrigger) inpostSelect._syncTrigger();
|
|
}
|
|
if (apaczkaSelect) {
|
|
apaczkaSelect.selectedIndex = 0;
|
|
if (apaczkaSelect._syncTrigger) apaczkaSelect._syncTrigger();
|
|
}
|
|
allegroOpts.forEach(function (o) { o.classList.remove('is-selected'); });
|
|
showPanel(carrierSelect.value);
|
|
});
|
|
|
|
if (inpostSelect) {
|
|
function syncInpostFields() {
|
|
var opt = inpostSelect.options[inpostSelect.selectedIndex];
|
|
hiddenInput.value = inpostSelect.value;
|
|
credentialsInput.value = opt ? (opt.getAttribute('data-credentials-id') || '') : '';
|
|
carrierInput.value = opt ? (opt.getAttribute('data-carrier-id') || '') : '';
|
|
if (providerInput) providerInput.value = 'allegro_wza';
|
|
}
|
|
inpostSelect.addEventListener('change', syncInpostFields);
|
|
if (carrierSelect.value === 'inpost' && inpostSelect.value !== '') {
|
|
syncInpostFields();
|
|
}
|
|
}
|
|
|
|
if (apaczkaSelect) {
|
|
function syncApaczkaFields() {
|
|
var opt = apaczkaSelect.options[apaczkaSelect.selectedIndex];
|
|
hiddenInput.value = apaczkaSelect.value;
|
|
credentialsInput.value = '';
|
|
carrierInput.value = opt ? (opt.getAttribute('data-carrier-id') || '') : '';
|
|
if (providerInput) providerInput.value = 'apaczka';
|
|
}
|
|
apaczkaSelect.addEventListener('change', syncApaczkaFields);
|
|
if (carrierSelect.value === 'apaczka' && apaczkaSelect.value !== '') {
|
|
syncApaczkaFields();
|
|
}
|
|
}
|
|
|
|
if (wrapper && searchInput && dropdown) {
|
|
var isAllegroOpen = false;
|
|
|
|
function selectAllegroOption(opt) {
|
|
hiddenInput.value = opt.getAttribute('data-value') || '';
|
|
credentialsInput.value = opt.getAttribute('data-credentials-id') || '';
|
|
carrierInput.value = opt.getAttribute('data-carrier-id') || '';
|
|
if (providerInput) providerInput.value = 'allegro_wza';
|
|
searchInput.value = opt.getAttribute('data-label') || '';
|
|
closeAllegro();
|
|
allegroOpts.forEach(function (o) { o.classList.remove('is-selected'); });
|
|
opt.classList.add('is-selected');
|
|
}
|
|
|
|
function openAllegro() {
|
|
dropdown.classList.add('is-open');
|
|
isAllegroOpen = true;
|
|
}
|
|
|
|
function closeAllegro() {
|
|
dropdown.classList.remove('is-open');
|
|
isAllegroOpen = false;
|
|
}
|
|
|
|
function filterAllegro(q) {
|
|
q = q.toLowerCase().trim();
|
|
allegroOpts.forEach(function (opt) {
|
|
var label = (opt.getAttribute('data-label') || '').toLowerCase();
|
|
opt.style.display = q === '' || label.indexOf(q) !== -1 ? '' : 'none';
|
|
});
|
|
}
|
|
|
|
searchInput.addEventListener('focus', function () {
|
|
filterAllegro(searchInput.value);
|
|
openAllegro();
|
|
});
|
|
|
|
searchInput.addEventListener('input', function () {
|
|
filterAllegro(searchInput.value);
|
|
if (!isAllegroOpen) openAllegro();
|
|
});
|
|
|
|
allegroOpts.forEach(function (opt) {
|
|
opt.addEventListener('mousedown', function (e) {
|
|
e.preventDefault();
|
|
selectAllegroOption(opt);
|
|
});
|
|
});
|
|
|
|
searchInput.addEventListener('blur', function () {
|
|
setTimeout(closeAllegro, 150);
|
|
});
|
|
|
|
searchInput.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape') {
|
|
closeAllegro();
|
|
searchInput.blur();
|
|
}
|
|
});
|
|
|
|
if (carrierSelect.value === 'allegro') {
|
|
var matchId = (wrapper.getAttribute('data-match-id') || '').trim();
|
|
if (matchId !== '') {
|
|
allegroOpts.forEach(function (opt) {
|
|
if (opt.getAttribute('data-value') === matchId) {
|
|
selectAllegroOption(opt);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function checkPackageStatus(pkgId, oId, btn, attempt) {
|
|
if (btn) {
|
|
btn.disabled = true;
|
|
btn.textContent = 'Sprawdzam...';
|
|
}
|
|
fetch('/orders/' + oId + '/shipment/' + pkgId + '/status')
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
if (data.status === 'label_ready') {
|
|
window.location.reload();
|
|
} else if (data.status === 'created' || data.status === 'in_progress' || data.status === 'pending') {
|
|
if (attempt < 10) {
|
|
var delayCreated = Math.min(2000 * Math.pow(1.5, attempt), 15000);
|
|
setTimeout(function () {
|
|
checkPackageStatus(pkgId, oId, btn, attempt + 1);
|
|
}, delayCreated);
|
|
if (btn) btn.textContent = 'Generuje etykiete... (' + (attempt + 1) + ')';
|
|
} else if (btn) {
|
|
btn.textContent = 'W toku... Odswiez status';
|
|
btn.disabled = false;
|
|
}
|
|
} else if (data.status === 'error') {
|
|
if (btn) {
|
|
btn.textContent = 'Blad: ' + (data.error || '');
|
|
btn.disabled = false;
|
|
}
|
|
} else {
|
|
if (btn) {
|
|
btn.textContent = 'W toku... Sprobuj ponownie';
|
|
btn.disabled = false;
|
|
}
|
|
}
|
|
})
|
|
.catch(function () {
|
|
if (btn) {
|
|
btn.textContent = 'Blad sieci';
|
|
btn.disabled = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
document.querySelectorAll('[data-check-status]').forEach(function (btn) {
|
|
btn.addEventListener('click', function () {
|
|
checkPackageStatus(
|
|
btn.getAttribute('data-check-status'),
|
|
btn.getAttribute('data-order-id'),
|
|
btn,
|
|
0
|
|
);
|
|
});
|
|
});
|
|
|
|
// Print label button handler
|
|
document.querySelectorAll('.btn-print-label').forEach(function (btn) {
|
|
btn.addEventListener('click', function () {
|
|
var packageId = btn.getAttribute('data-package-id');
|
|
if (!packageId) return;
|
|
btn.disabled = true;
|
|
var originalText = btn.innerHTML;
|
|
btn.innerHTML = 'Wysylam...';
|
|
|
|
fetch('/api/print/jobs', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
body: '_token=' + encodeURIComponent(document.querySelector('input[name="_token"]').value)
|
|
+ '&package_id=' + encodeURIComponent(packageId)
|
|
})
|
|
.then(function (r) { return r.json().then(function (d) { return { status: r.status, data: d }; }); })
|
|
.then(function (res) {
|
|
if (res.status === 201 || res.status === 409) {
|
|
btn.innerHTML = 'W kolejce';
|
|
btn.disabled = true;
|
|
btn.classList.remove('btn--secondary');
|
|
btn.classList.add('btn--danger');
|
|
} else {
|
|
var msg = (res.data && res.data.error) ? res.data.error : 'Nieznany blad';
|
|
if (window.OrderProAlerts) {
|
|
window.OrderProAlerts.show({ message: msg, type: 'error' });
|
|
}
|
|
btn.innerHTML = originalText;
|
|
btn.disabled = false;
|
|
}
|
|
})
|
|
.catch(function () {
|
|
if (window.OrderProAlerts) {
|
|
window.OrderProAlerts.show({ message: 'Blad sieci — sprobuj ponownie.', type: 'error' });
|
|
}
|
|
btn.innerHTML = originalText;
|
|
btn.disabled = false;
|
|
});
|
|
});
|
|
});
|
|
|
|
var params = new URLSearchParams(window.location.search);
|
|
var autoCheckId = params.get('check');
|
|
|
|
document.querySelectorAll('[data-check-status][data-auto-check=\"1\"]').forEach(function (btn, idx) {
|
|
var pkgId = btn.getAttribute('data-check-status');
|
|
var oId = btn.getAttribute('data-order-id');
|
|
var pkgStatus = (btn.getAttribute('data-package-status') || '').toLowerCase();
|
|
if (!pkgId || !oId) return;
|
|
|
|
if (autoCheckId) {
|
|
if (pkgId !== autoCheckId) return;
|
|
} else {
|
|
if (pkgStatus !== 'pending') return;
|
|
}
|
|
|
|
setTimeout(function () {
|
|
checkPackageStatus(pkgId, oId, btn, 0);
|
|
}, idx * 400);
|
|
});
|
|
|
|
})();
|
|
</script>
|
|
<script>
|
|
(function () {
|
|
'use strict';
|
|
|
|
var PRESET_COLORS = ['#3b82f6','#ef4444','#10b981','#f59e0b','#8b5cf6','#ec4899','#06b6d4','#6b7280'];
|
|
var presetsContainer = document.getElementById('shipment-presets');
|
|
var addBtn = document.getElementById('preset-add-btn');
|
|
var modal = document.getElementById('preset-modal');
|
|
var nameInput = document.getElementById('preset-name-input');
|
|
var colorPicker = document.getElementById('preset-color-picker');
|
|
var saveBtn = document.getElementById('preset-save-btn');
|
|
var cancelBtn = document.getElementById('preset-cancel-btn');
|
|
|
|
if (!presetsContainer || !addBtn || !modal) return;
|
|
|
|
var selectedColor = PRESET_COLORS[0];
|
|
var presetsData = [];
|
|
|
|
// --- Color picker ---
|
|
PRESET_COLORS.forEach(function (color, idx) {
|
|
var swatch = document.createElement('div');
|
|
swatch.className = 'preset-modal__color-swatch' + (idx === 0 ? ' is-selected' : '');
|
|
swatch.style.background = color;
|
|
swatch.setAttribute('data-color', color);
|
|
swatch.addEventListener('click', function () {
|
|
colorPicker.querySelectorAll('.preset-modal__color-swatch').forEach(function (s) { s.classList.remove('is-selected'); });
|
|
swatch.classList.add('is-selected');
|
|
selectedColor = color;
|
|
});
|
|
colorPicker.appendChild(swatch);
|
|
});
|
|
|
|
// --- Load presets ---
|
|
function loadPresets() {
|
|
fetch('/api/shipment-presets', { credentials: 'same-origin' })
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
presetsData = data.presets || [];
|
|
renderPresets();
|
|
})
|
|
.catch(function () {});
|
|
}
|
|
|
|
var activeDropdown = null;
|
|
|
|
function renderPresets() {
|
|
var existing = presetsContainer.querySelectorAll('.shipment-presets__btn-wrap');
|
|
existing.forEach(function (el) { el.remove(); });
|
|
|
|
presetsData.forEach(function (preset) {
|
|
var wrap = document.createElement('div');
|
|
wrap.className = 'shipment-presets__btn-wrap';
|
|
|
|
var btn = document.createElement('button');
|
|
btn.type = 'button';
|
|
btn.className = 'shipment-presets__btn';
|
|
btn.style.background = preset.color || '#3b82f6';
|
|
btn.textContent = preset.name;
|
|
btn.setAttribute('data-preset-id', preset.id);
|
|
btn.addEventListener('click', function () { applyPreset(preset); });
|
|
|
|
var editIcon = document.createElement('button');
|
|
editIcon.type = 'button';
|
|
editIcon.className = 'shipment-presets__edit-icon';
|
|
editIcon.textContent = '\u270E';
|
|
editIcon.addEventListener('click', function (e) {
|
|
e.stopPropagation();
|
|
showDropdown(wrap, preset);
|
|
});
|
|
|
|
wrap.appendChild(btn);
|
|
wrap.appendChild(editIcon);
|
|
presetsContainer.insertBefore(wrap, addBtn);
|
|
});
|
|
}
|
|
|
|
// --- Dropdown menu ---
|
|
function closeDropdown() {
|
|
if (activeDropdown) {
|
|
activeDropdown.remove();
|
|
activeDropdown = null;
|
|
}
|
|
}
|
|
|
|
document.addEventListener('click', function () { closeDropdown(); });
|
|
|
|
function showDropdown(wrap, preset) {
|
|
closeDropdown();
|
|
|
|
var dd = document.createElement('div');
|
|
dd.className = 'shipment-presets__dropdown';
|
|
|
|
var editItem = document.createElement('div');
|
|
editItem.className = 'shipment-presets__dropdown-item';
|
|
editItem.textContent = 'Edytuj nazw\u0119 i kolor';
|
|
editItem.addEventListener('click', function (e) {
|
|
e.stopPropagation();
|
|
closeDropdown();
|
|
openEditModal(preset);
|
|
});
|
|
|
|
var updateItem = document.createElement('div');
|
|
updateItem.className = 'shipment-presets__dropdown-item';
|
|
updateItem.textContent = 'Zapisz bie\u017C\u0105ce warto\u015Bci';
|
|
updateItem.addEventListener('click', function (e) {
|
|
e.stopPropagation();
|
|
closeDropdown();
|
|
saveCurrentValues(preset);
|
|
});
|
|
|
|
var deleteItem = document.createElement('div');
|
|
deleteItem.className = 'shipment-presets__dropdown-item is-danger';
|
|
deleteItem.textContent = 'Usu\u0144';
|
|
deleteItem.addEventListener('click', function (e) {
|
|
e.stopPropagation();
|
|
closeDropdown();
|
|
deletePreset(preset);
|
|
});
|
|
|
|
dd.appendChild(editItem);
|
|
dd.appendChild(updateItem);
|
|
dd.appendChild(deleteItem);
|
|
wrap.appendChild(dd);
|
|
activeDropdown = dd;
|
|
}
|
|
|
|
// --- Apply preset (autofill form) ---
|
|
function applyPreset(preset) {
|
|
var carrierSelect = document.getElementById('shipment-carrier-select');
|
|
var hiddenInput = document.getElementById('shipment-delivery-service');
|
|
var credentialsInput = document.getElementById('shipment-credentials-id');
|
|
var carrierInput = document.getElementById('shipment-carrier-id');
|
|
var providerInput = document.getElementById('shipment-provider-code');
|
|
|
|
if (!carrierSelect) return;
|
|
|
|
// Set carrier — use native change so existing handler shows correct panel
|
|
carrierSelect.value = preset.carrier || '';
|
|
if (carrierSelect._syncTrigger) carrierSelect._syncTrigger();
|
|
carrierSelect.dispatchEvent(new Event('change'));
|
|
|
|
// The existing change handler clears hidden fields and resets selects.
|
|
// We must wait for that to finish, then override with preset values.
|
|
setTimeout(function () {
|
|
// Hidden fields — set AFTER the change handler cleared them
|
|
if (hiddenInput) hiddenInput.value = preset.delivery_method_id || '';
|
|
if (credentialsInput) credentialsInput.value = preset.credentials_id || '';
|
|
if (carrierInput) carrierInput.value = preset.carrier_id || '';
|
|
if (providerInput) providerInput.value = preset.provider_code || '';
|
|
|
|
// Package fields
|
|
setFieldValue('package_type', preset.package_type || 'PACKAGE');
|
|
setFieldValue('length_cm', preset.length_cm || '25');
|
|
setFieldValue('width_cm', preset.width_cm || '20');
|
|
setFieldValue('height_cm', preset.height_cm || '8');
|
|
setFieldValue('weight_kg', preset.weight_kg || '1');
|
|
setFieldValue('sender_point_id', preset.sender_point_id || '');
|
|
setFieldValue('label_format', preset.label_format || 'PDF');
|
|
|
|
// Select delivery service in the correct panel
|
|
selectDeliveryService(preset);
|
|
}, 200);
|
|
}
|
|
|
|
function setFieldValue(name, value) {
|
|
var field = document.querySelector('[name="' + name + '"]');
|
|
if (!field) return;
|
|
field.value = value;
|
|
if (field.tagName === 'SELECT' && field._syncTrigger) {
|
|
field._syncTrigger();
|
|
}
|
|
}
|
|
|
|
function selectDeliveryService(preset) {
|
|
var carrier = preset.carrier || '';
|
|
var methodId = preset.delivery_method_id || '';
|
|
var credentialsId = preset.credentials_id || '';
|
|
var carrierId = preset.carrier_id || '';
|
|
|
|
var hiddenInput = document.getElementById('shipment-delivery-service');
|
|
var credentialsInput = document.getElementById('shipment-credentials-id');
|
|
var carrierInput = document.getElementById('shipment-carrier-id');
|
|
|
|
if (carrier === 'allegro') {
|
|
// Click the matching option in Allegro searchable dropdown
|
|
var dropdown = document.getElementById('shipment-service-dropdown');
|
|
if (dropdown) {
|
|
var opts = dropdown.querySelectorAll('.searchable-select__option');
|
|
opts.forEach(function (opt) {
|
|
opt.classList.remove('is-selected');
|
|
if (opt.getAttribute('data-value') === methodId) {
|
|
opt.classList.add('is-selected');
|
|
// Update search input to show selected service name
|
|
var searchInput = document.getElementById('shipment-service-search');
|
|
if (searchInput) searchInput.value = opt.getAttribute('data-label') || opt.textContent.trim();
|
|
// Set hidden fields from option data attributes
|
|
if (hiddenInput) hiddenInput.value = methodId;
|
|
if (credentialsInput) credentialsInput.value = opt.getAttribute('data-credentials-id') || credentialsId;
|
|
if (carrierInput) carrierInput.value = opt.getAttribute('data-carrier-id') || carrierId;
|
|
}
|
|
});
|
|
}
|
|
} else if (carrier === 'inpost') {
|
|
var inpostSelect = document.getElementById('shipment-inpost-select');
|
|
if (inpostSelect) {
|
|
inpostSelect.value = methodId;
|
|
if (inpostSelect._syncTrigger) inpostSelect._syncTrigger();
|
|
// Trigger change to set hidden fields via existing handler
|
|
inpostSelect.dispatchEvent(new Event('change'));
|
|
}
|
|
} else if (carrier === 'apaczka') {
|
|
var apaczkaSelect = document.getElementById('shipment-apaczka-select');
|
|
if (apaczkaSelect) {
|
|
apaczkaSelect.value = methodId;
|
|
if (apaczkaSelect._syncTrigger) apaczkaSelect._syncTrigger();
|
|
// Trigger change to set hidden fields via existing handler
|
|
apaczkaSelect.dispatchEvent(new Event('change'));
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- Modal (create & edit) ---
|
|
var editingPresetId = 0;
|
|
var modalTitle = modal.querySelector('h3');
|
|
|
|
function openCreateModal() {
|
|
editingPresetId = 0;
|
|
nameInput.value = '';
|
|
selectedColor = PRESET_COLORS[0];
|
|
colorPicker.querySelectorAll('.preset-modal__color-swatch').forEach(function (s, i) {
|
|
s.classList.toggle('is-selected', i === 0);
|
|
});
|
|
if (modalTitle) modalTitle.textContent = 'Nowy przycisk dostawy';
|
|
saveBtn.textContent = 'Zapisz';
|
|
modal.style.display = '';
|
|
nameInput.focus();
|
|
}
|
|
|
|
function openEditModal(preset) {
|
|
editingPresetId = preset.id;
|
|
nameInput.value = preset.name || '';
|
|
selectedColor = preset.color || PRESET_COLORS[0];
|
|
colorPicker.querySelectorAll('.preset-modal__color-swatch').forEach(function (s) {
|
|
s.classList.toggle('is-selected', s.getAttribute('data-color') === selectedColor);
|
|
});
|
|
if (modalTitle) modalTitle.textContent = 'Edytuj przycisk dostawy';
|
|
saveBtn.textContent = 'Zapisz zmiany';
|
|
modal.style.display = '';
|
|
nameInput.focus();
|
|
}
|
|
|
|
addBtn.addEventListener('click', function () { openCreateModal(); });
|
|
|
|
cancelBtn.addEventListener('click', function () {
|
|
modal.style.display = 'none';
|
|
});
|
|
|
|
modal.addEventListener('click', function (e) {
|
|
if (e.target === modal) modal.style.display = 'none';
|
|
});
|
|
|
|
saveBtn.addEventListener('click', function () {
|
|
var name = nameInput.value.trim();
|
|
if (!name) {
|
|
nameInput.focus();
|
|
return;
|
|
}
|
|
|
|
saveBtn.disabled = true;
|
|
|
|
if (editingPresetId > 0) {
|
|
// Edit mode — update name and color only, keep existing params
|
|
var editPreset = presetsData.find(function (p) { return p.id === editingPresetId; });
|
|
var editPayload = {
|
|
id: editingPresetId,
|
|
name: name,
|
|
color: selectedColor,
|
|
carrier: editPreset ? editPreset.carrier : '',
|
|
provider_code: editPreset ? editPreset.provider_code : '',
|
|
delivery_method_id: editPreset ? editPreset.delivery_method_id : '',
|
|
credentials_id: editPreset ? editPreset.credentials_id : '',
|
|
carrier_id: editPreset ? editPreset.carrier_id : '',
|
|
package_type: editPreset ? editPreset.package_type : 'PACKAGE',
|
|
length_cm: editPreset ? editPreset.length_cm : '25',
|
|
width_cm: editPreset ? editPreset.width_cm : '20',
|
|
height_cm: editPreset ? editPreset.height_cm : '8',
|
|
weight_kg: editPreset ? editPreset.weight_kg : '1',
|
|
sender_point_id: editPreset ? editPreset.sender_point_id : '',
|
|
label_format: editPreset ? editPreset.label_format : 'PDF'
|
|
};
|
|
postPresetAPI('/api/shipment-presets/update', editPayload);
|
|
} else {
|
|
// Create mode — use current form values
|
|
var payload = buildFormPayload(name, selectedColor);
|
|
postPresetAPI('/api/shipment-presets', payload);
|
|
}
|
|
});
|
|
|
|
function buildFormPayload(name, color) {
|
|
var carrierSelect = document.getElementById('shipment-carrier-select');
|
|
var hiddenInput = document.getElementById('shipment-delivery-service');
|
|
var credentialsInput = document.getElementById('shipment-credentials-id');
|
|
var carrierInput = document.getElementById('shipment-carrier-id');
|
|
var providerInput = document.getElementById('shipment-provider-code');
|
|
|
|
return {
|
|
name: name,
|
|
color: color,
|
|
carrier: carrierSelect ? carrierSelect.value : '',
|
|
provider_code: providerInput ? providerInput.value : '',
|
|
delivery_method_id: hiddenInput ? hiddenInput.value : '',
|
|
credentials_id: credentialsInput ? credentialsInput.value : '',
|
|
carrier_id: carrierInput ? carrierInput.value : '',
|
|
package_type: getFieldValue('package_type'),
|
|
length_cm: getFieldValue('length_cm'),
|
|
width_cm: getFieldValue('width_cm'),
|
|
height_cm: getFieldValue('height_cm'),
|
|
weight_kg: getFieldValue('weight_kg'),
|
|
sender_point_id: getFieldValue('sender_point_id'),
|
|
label_format: getFieldValue('label_format')
|
|
};
|
|
}
|
|
|
|
function postPresetAPI(url, payload) {
|
|
var formBody = new URLSearchParams(payload);
|
|
fetch(url, {
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
body: formBody.toString()
|
|
})
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
if (data.preset || data.deleted) {
|
|
modal.style.display = 'none';
|
|
loadPresets();
|
|
}
|
|
})
|
|
.catch(function () {})
|
|
.finally(function () { saveBtn.disabled = false; });
|
|
}
|
|
|
|
// --- Save current form values to existing preset ---
|
|
function saveCurrentValues(preset) {
|
|
var payload = buildFormPayload(preset.name, preset.color);
|
|
payload.id = preset.id;
|
|
postPresetAPI('/api/shipment-presets/update', payload);
|
|
}
|
|
|
|
// --- Delete preset ---
|
|
function deletePreset(preset) {
|
|
if (window.OrderProAlerts && window.OrderProAlerts.confirm) {
|
|
window.OrderProAlerts.confirm({
|
|
message: 'Usun\u0105\u0107 przycisk "' + preset.name + '"?',
|
|
onConfirm: function () { executeDelete(preset.id); }
|
|
});
|
|
} else if (confirm('Usun\u0105\u0107 przycisk "' + preset.name + '"?')) {
|
|
executeDelete(preset.id);
|
|
}
|
|
}
|
|
|
|
function executeDelete(id) {
|
|
var formBody = new URLSearchParams({ id: id });
|
|
fetch('/api/shipment-presets/delete', {
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
body: formBody.toString()
|
|
})
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
if (data.deleted) loadPresets();
|
|
})
|
|
.catch(function () {});
|
|
}
|
|
|
|
function getFieldValue(name) {
|
|
var field = document.querySelector('[name="' + name + '"]');
|
|
return field ? field.value : '';
|
|
}
|
|
|
|
// --- Init ---
|
|
loadPresets();
|
|
|
|
})();
|
|
</script>
|