This commit is contained in:
2026-03-30 20:23:38 +02:00
parent 70662afd2c
commit 5435209b08
26 changed files with 1949 additions and 160 deletions

View File

@@ -444,12 +444,20 @@ foreach ($addressesList as $address) {
<?php if ($isManual): ?>
<span class="order-tag is-neutral">Dodana recznie</span>
<?php else: ?>
<span class="order-tag <?= $pkgStatus === 'label_ready' || $pkgStatus === 'created' ? 'is-success' : ($pkgStatus === 'error' ? 'is-danger' : 'is-warn') ?>">
<span class="order-tag <?= $pkgStatus === 'label_ready' || $pkgStatus === 'created' ? 'is-success' : ($pkgStatus === 'error' ? 'is-danger' : 'is-warn') ?>"
data-pkg-status-tag="<?= $e((string) ($pkg['id'] ?? 0)) ?>">
<?= $e($pkgStatus) ?>
</span>
<?php if ($pkgStatus === 'pending'): ?>
<button type="button" class="btn btn--xs btn--secondary mt-4"
data-check-pkg-status="<?= $e((string) ($pkg['id'] ?? 0)) ?>"
data-order-id="<?= $e((string) ($orderId ?? 0)) ?>"
data-auto-poll="1"
style="font-size:0.7rem">Sprawdz status</button>
<?php endif; ?>
<?php endif; ?>
<?php if ($pkgError !== ''): ?>
<div class="muted mt-4" style="font-size:0.75rem"><?= $e($pkgError) ?></div>
<div class="muted mt-4" style="font-size:0.75rem" data-pkg-error="<?= $e((string) ($pkg['id'] ?? 0)) ?>"><?= $e($pkgError) ?></div>
<?php endif; ?>
</td>
<td>
@@ -462,13 +470,13 @@ foreach ($addressesList as $address) {
?>
<span class="delivery-badge delivery-badge--<?= $e($pkgDeliveryStatus) ?>" title="<?= $e($pkgDeliveryTitle) ?>"><?= $e($pkgDeliveryLabel) ?></span>
</td>
<td style="white-space:nowrap">
<td style="white-space:nowrap" data-pkg-tracking-cell="<?= $e((string) ($pkg['id'] ?? 0)) ?>">
<?= $e($pkgTracking !== '' ? $pkgTracking : '-') ?><?php
$pkgTrackUrl = \App\Modules\Shipments\DeliveryStatus::trackingUrl($pkgProvider, $pkgTracking, $pkgCarrierId);
if ($pkgTrackUrl !== null): ?> <a href="<?= $e($pkgTrackUrl) ?>" target="_blank" class="tracking-link" title="Sledz przesylke">&#128279;</a><?php endif; ?>
</td>
<td><?php if ($isManual): ?><?= $e($pkgCarrierId !== '' ? $pkgCarrierId : 'Reczna') ?><?php elseif ($pkgCarrierId !== ''): ?><?= $e($pkgProviderLabel) ?> &rarr; <?= $e($pkgCarrierId) ?><?php elseif ($pkgProviderLabel !== ''): ?><?= $e($pkgProviderLabel) ?><?php else: ?>-<?php endif; ?></td>
<td>
<td data-pkg-label-cell="<?= $e((string) ($pkg['id'] ?? 0)) ?>">
<?php if ($isManual): ?>
&mdash;
<?php else: ?>
@@ -595,8 +603,42 @@ foreach ($addressesList as $address) {
</div>
</div>
<div class="mt-12">
<button type="button" class="btn btn--sm btn--primary" id="btn-add-payment">+ Dodaj płatność</button>
</div>
<div class="payment-add-form mt-12" id="payment-add-form" style="display:none">
<div class="payment-add-form__row">
<div class="payment-add-form__field">
<label for="payment-amount">Kwota</label>
<input type="number" id="payment-amount" step="0.01" min="0.01" required
value="<?= $e(number_format(max(0, (float) ($orderRow['total_with_tax'] ?? 0) - (float) ($orderRow['total_paid'] ?? 0)), 2, '.', '')) ?>">
</div>
<div class="payment-add-form__field">
<label for="payment-type">Typ płatności</label>
<select id="payment-type" required>
<option value="ONLINE">Płatność online</option>
<option value="TRANSFER">Przelew bankowy</option>
<option value="CASH_ON_DELIVERY">Za pobraniem</option>
</select>
</div>
<div class="payment-add-form__field">
<label for="payment-date">Data</label>
<input type="date" id="payment-date" value="<?= $e(date('Y-m-d')) ?>">
</div>
<div class="payment-add-form__field">
<label for="payment-comment">Komentarz</label>
<input type="text" id="payment-comment" placeholder="opcjonalny">
</div>
</div>
<div class="payment-add-form__actions mt-8">
<button type="button" class="btn btn--sm btn--primary" id="btn-save-payment">Zapisz</button>
<button type="button" class="btn btn--sm btn--outline" id="btn-cancel-payment">Anuluj</button>
</div>
</div>
<?php if ($paymentsList === []): ?>
<p class="muted mt-16">Brak zarejestrowanych płatności.</p>
<p class="muted mt-16" id="payments-empty-msg">Brak zarejestrowanych płatności.</p>
<?php else: ?>
<div class="table-wrap mt-16">
<table class="table table--details">
@@ -739,41 +781,41 @@ foreach ($addressesList as $address) {
try { savedTab = localStorage.getItem(storageKey); } catch (e) {}
setActiveTab(forceTab || savedTab || 'details');
// 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...';
var csrfInput = document.querySelector('input[name="_token"]');
var csrf = csrfInput ? csrfInput.value : '<?= $e($csrfToken ?? '') ?>';
// Print label button handler (delegated for dynamically added buttons)
document.addEventListener('click', function (e) {
var btn = e.target.closest('.btn-print-label');
if (!btn) return;
var packageId = btn.getAttribute('data-package-id');
if (!packageId) return;
btn.disabled = true;
var originalText = btn.innerHTML;
btn.innerHTML = 'Wysylam...';
var csrfInput = document.querySelector('input[name="_token"]');
var csrf = csrfInput ? csrfInput.value : '<?= $e($csrfToken ?? '') ?>';
fetch('/api/print/jobs', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: '_token=' + encodeURIComponent(csrf) + '&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.', type: 'error' }); }
fetch('/api/print/jobs', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: '_token=' + encodeURIComponent(csrf) + '&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.', type: 'error' }); }
btn.innerHTML = originalText;
btn.disabled = false;
});
});
@@ -805,4 +847,184 @@ foreach ($addressesList as $address) {
})();
</script>
<script>
(function () {
'use strict';
var csrfToken = (document.querySelector('input[name="_token"]') || {}).value || '';
function updateRowSuccess(pkgId, orderId, data) {
var tag = document.querySelector('[data-pkg-status-tag="' + pkgId + '"]');
if (tag) {
tag.className = 'order-tag is-success';
tag.textContent = data.status;
}
var btn = document.querySelector('[data-check-pkg-status="' + pkgId + '"]');
if (btn) btn.remove();
var trackingCell = document.querySelector('[data-pkg-tracking-cell="' + pkgId + '"]');
if (trackingCell && data.tracking_number) {
trackingCell.textContent = data.tracking_number;
}
var labelCell = document.querySelector('[data-pkg-label-cell="' + pkgId + '"]');
if (labelCell) {
var html = '<span style="display:inline-flex;gap:4px;align-items:center">';
if (data.status === 'label_ready') {
html += '<form method="post" action="/orders/' + orderId + '/shipment/' + pkgId + '/label" style="display:inline">'
+ '<input type="hidden" name="_token" value="' + csrfToken + '">'
+ '<button type="submit" class="btn btn--sm btn--secondary">Pobierz</button></form>';
}
html += '<button type="button" class="btn btn--sm btn--secondary btn-print-label"'
+ ' data-package-id="' + pkgId + '" data-order-id="' + orderId + '" title="Wyslij do drukarki">Drukuj</button>';
html += '</span>';
labelCell.innerHTML = html;
}
}
function updateRowError(pkgId, errorMsg) {
var tag = document.querySelector('[data-pkg-status-tag="' + pkgId + '"]');
if (tag) {
tag.className = 'order-tag is-danger';
tag.textContent = 'error';
}
var btn = document.querySelector('[data-check-pkg-status="' + pkgId + '"]');
if (btn) btn.remove();
var errEl = document.querySelector('[data-pkg-error="' + pkgId + '"]');
if (!errEl && tag) {
errEl = document.createElement('div');
errEl.className = 'muted mt-4';
errEl.style.fontSize = '0.75rem';
errEl.setAttribute('data-pkg-error', pkgId);
tag.parentNode.appendChild(errEl);
}
if (errEl) errEl.textContent = errorMsg || 'Blad tworzenia przesylki';
}
function pollPackageStatus(pkgId, orderId, btn, attempt) {
if (btn) {
btn.disabled = true;
btn.textContent = 'Sprawdzam... (' + (attempt + 1) + ')';
}
fetch('/orders/' + orderId + '/shipment/' + pkgId + '/status')
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.status === 'label_ready' || data.status === 'created') {
updateRowSuccess(pkgId, orderId, data);
} else if (data.status === 'in_progress' || data.status === 'pending') {
if (attempt < 12) {
var delay = Math.min(2000 * Math.pow(1.5, attempt), 15000);
setTimeout(function () {
pollPackageStatus(pkgId, orderId, btn, attempt + 1);
}, delay);
} else if (btn) {
btn.textContent = 'Sprawdz ponownie';
btn.disabled = false;
}
} else if (data.status === 'error') {
updateRowError(pkgId, data.error);
}
})
.catch(function () {
if (btn) {
btn.textContent = 'Blad sieci';
btn.disabled = false;
}
});
}
document.querySelectorAll('[data-check-pkg-status]').forEach(function (btn) {
btn.addEventListener('click', function () {
pollPackageStatus(
btn.getAttribute('data-check-pkg-status'),
btn.getAttribute('data-order-id'),
btn,
0
);
});
});
document.querySelectorAll('[data-check-pkg-status][data-auto-poll="1"]').forEach(function (btn, idx) {
setTimeout(function () {
pollPackageStatus(
btn.getAttribute('data-check-pkg-status'),
btn.getAttribute('data-order-id'),
btn,
0
);
}, 500 + idx * 400);
});
})();
</script>
<script>
(function () {
var btnAdd = document.getElementById('btn-add-payment');
var btnSave = document.getElementById('btn-save-payment');
var btnCancel = document.getElementById('btn-cancel-payment');
var form = document.getElementById('payment-add-form');
if (!btnAdd || !form) return;
btnAdd.addEventListener('click', function () {
form.style.display = '';
btnAdd.style.display = 'none';
});
btnCancel.addEventListener('click', function () {
form.style.display = 'none';
btnAdd.style.display = '';
});
btnSave.addEventListener('click', function () {
var amount = parseFloat(document.getElementById('payment-amount').value);
var paymentType = document.getElementById('payment-type').value;
var paymentDate = document.getElementById('payment-date').value;
var comment = document.getElementById('payment-comment').value;
if (!amount || amount <= 0) {
window.OrderProAlerts.error('Kwota musi być większa od 0.');
return;
}
if (!paymentType) {
window.OrderProAlerts.error('Wybierz typ płatności.');
return;
}
btnSave.disabled = true;
btnSave.textContent = 'Zapisywanie...';
var xhr = new XMLHttpRequest();
xhr.open('POST', '/orders/<?= (int) $orderId ?>/payment/add', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function () {
var resp;
try { resp = JSON.parse(xhr.responseText); } catch (e) { resp = {}; }
if (xhr.status >= 200 && xhr.status < 300 && resp.ok) {
window.location.reload();
} else {
window.OrderProAlerts.error(resp.error || 'Błąd zapisu płatności.');
btnSave.disabled = false;
btnSave.textContent = 'Zapisz';
}
};
xhr.onerror = function () {
window.OrderProAlerts.error('Błąd połączenia z serwerem.');
btnSave.disabled = false;
btnSave.textContent = 'Zapisz';
};
xhr.send(
'_token=<?= $e($csrfToken) ?>' +
'&amount=' + encodeURIComponent(amount) +
'&payment_type_id=' + encodeURIComponent(paymentType) +
'&payment_date=' + encodeURIComponent(paymentDate) +
'&comment=' + encodeURIComponent(comment)
);
});
})();
</script>
<?php require __DIR__ . '/partials/email-send-modal.php'; ?>