feat: Enhance InPost service selection and handling in Allegro settings

- Added a check for available InPost services and display a message if none are found.
- Updated the InPost service selection dropdown to include additional data attributes for better handling in JavaScript.
- Improved JavaScript event handling for InPost service selection to correctly populate hidden fields with selected service data.

feat: Introduce Cash on Delivery (COD) functionality in shipment preparation

- Added a new input field for specifying the COD amount and currency in the shipment preparation view.
- Updated the shipment creation logic to handle COD amounts correctly when creating shipments.

refactor: Update OrdersController to include shipment package repository

- Modified the OrdersController to accept a ShipmentPackageRepository for better management of shipment-related data.
- Enhanced order details to include shipment package information.

fix: Ensure internal order numbers are generated upon order creation

- Updated the OrderImportRepository to generate and store internal order numbers when a new order is created.

feat: Implement status synchronization for Allegro orders

- Introduced a new service for syncing order statuses from Allegro to the internal system.
- Added logic to fetch and process orders needing status updates, handling errors gracefully.

chore: Clean up InPost service definitions in AllegroIntegrationController

- Removed hardcoded InPost service definitions and replaced them with dynamic fetching based on available services.

feat: Add activity logging for shipment actions

- Implemented activity logging for various shipment actions, including creation, label downloads, and errors, to improve traceability and auditing.
This commit is contained in:
2026-03-06 20:09:59 +01:00
parent 1b5e403c31
commit 3ba6202770
21 changed files with 1888 additions and 226 deletions

View File

@@ -26,6 +26,8 @@ $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">
@@ -171,14 +173,30 @@ $currency = strtoupper(trim((string) ($orderRow['currency'] ?? 'PLN')));
</div>
<div id="shipment-inpost-panel" style="<?= $preselectedCarrier !== 'inpost' ? 'display:none' : '' ?>">
<select class="form-control" id="shipment-inpost-select">
<option value="">-- Wybierz usluge InPost --</option>
<?php foreach ($inpostSvcList as $inSvc): ?>
<option value="<?= $e((string) ($inSvc['id'] ?? '')) ?>"<?= $mappedCarrier === 'inpost' && $mappedMethodId === (string) ($inSvc['id'] ?? '') ? ' selected' : '' ?>>
<?= $e((string) ($inSvc['name'] ?? '')) ?>
</option>
<?php endforeach; ?>
</select>
<?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-empty-panel" class="muted" style="<?= $preselectedCarrier !== '' ? 'display:none' : '' ?>">Wybierz przewoznika</div>
@@ -230,6 +248,14 @@ $currency = strtoupper(trim((string) ($orderRow['currency'] ?? 'PLN')));
</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">
@@ -482,13 +508,15 @@ $currency = strtoupper(trim((string) ($orderRow['currency'] ?? 'PLN')));
// --- InPost select ---
if (inpostSelect) {
inpostSelect.addEventListener('change', function () {
function syncInpostFields() {
var opt = inpostSelect.options[inpostSelect.selectedIndex];
hiddenInput.value = inpostSelect.value;
credentialsInput.value = '';
carrierInput.value = '';
});
credentialsInput.value = opt ? (opt.getAttribute('data-credentials-id') || '') : '';
carrierInput.value = opt ? (opt.getAttribute('data-carrier-id') || '') : '';
}
inpostSelect.addEventListener('change', syncInpostFields);
if (carrierSelect.value === 'inpost' && inpostSelect.value !== '') {
hiddenInput.value = inpostSelect.value;
syncInpostFields();
}
}
@@ -573,7 +601,7 @@ $currency = strtoupper(trim((string) ($orderRow['currency'] ?? 'PLN')));
fetch('/orders/' + oId + '/shipment/' + pkgId + '/status')
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.status === 'created') {
if (data.status === 'created' || data.status === 'label_ready') {
window.location.reload();
} else if (data.status === 'error') {
if (btn) {