Offer 4x6 label downloads alongside A4
Deploy HickLab3D Dashboard / Deploy to production (push) Successful in 1m48s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Hickmeister
2026-10-11 20:39:34 +01:00
co-authored by Claude Sonnet 5.5
parent 51c6748894
commit dff81caaea
4 changed files with 22 additions and 5 deletions
+3 -2
View File
@@ -227,11 +227,12 @@ class ShippingController extends Controller
$order = collect($orders)->first(fn ($order) => (string) ($order['OrderLineId'] ?? '') === $orderLineId);
$hash = $order ? $parcel2Go->labelHash($order) : null;
abort_unless($hash, 404);
$pdf = $parcel2Go->labelPdf($orderLineId, $hash);
$size = $request->query('size') === '4x6' ? '4x6' : 'a4';
$pdf = $parcel2Go->labelPdf($orderLineId, $hash, $size === '4x6' ? 'Label4x6' : 'A4');
return response($pdf, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="parcel2go-'.$orderLineId.'.pdf"',
'Content-Disposition' => 'attachment; filename="parcel2go-'.$orderLineId.'-'.$size.'.pdf"',
'Cache-Control' => 'private, no-store',
]);
}
+3 -2
View File
@@ -182,13 +182,14 @@ class Parcel2Go
return filled($query['hash'] ?? null) ? (string) $query['hash'] : null;
}
public function labelPdf(string $reference, string $hash): string
/** @param 'A4'|'Label4x6' $media */
public function labelPdf(string $reference, string $hash, string $media = 'A4'): string
{
$token = $this->profileConnected() ? $this->profileAccessToken() : $this->accessToken();
$data = Http::withToken($token)->acceptJson()->connectTimeout(3)->timeout(20)
->get($this->url('labels/'.$reference), [
'referenceType' => 'OrderLineId', 'detailLevel' => 'Labels',
'labelMedia' => 'A4', 'labelFormat' => 'PDF', 'hash' => $hash,
'labelMedia' => $media, 'labelFormat' => 'PDF', 'hash' => $hash,
])->throw()->json();
$encoded = $data['Base64EncodedLabels'][0] ?? '';
$pdf = is_string($encoded) ? base64_decode($encoded, true) : false;
+1 -1
View File
@@ -35,7 +35,7 @@
<div class="p-6"><h3 class="text-lg font-semibold">Existing shipments</h3><p class="mt-1 text-sm text-slate-400">Current Parcel2Go progress and labels from your account history.</p></div>
<table class="w-full min-w-[800px] text-left text-sm"><thead class="border-y border-slate-800 text-slate-400"><tr><th class="p-4">Order</th><th class="p-4">Courier</th><th class="p-4">Service</th><th class="p-4">Progress</th><th class="p-4">Estimated delivery</th><th class="p-4">Recipient</th><th class="p-4">Destination</th><th class="p-4">Label</th></tr></thead><tbody class="divide-y divide-slate-800">
@forelse(($orders['Orders'] ?? []) as $order)
<tr><td class="p-4">{{ $order['OrderLineId'] ?? '—' }}</td><td class="p-4">{{ $order['Courier'] ?? '—' }}</td><td class="p-4">{{ $order['Service'] ?? '—' }}</td><td class="p-4"><span @class(['rounded-full px-2 py-1 text-xs font-semibold', 'bg-emerald-500/10 text-emerald-300' => $order['Tracking']['Delivered'] ?? false, 'bg-sky-500/10 text-sky-300' => ! ($order['Tracking']['Delivered'] ?? false)])>{{ ($order['Tracking']['Delivered'] ?? false) ? 'Delivered' : 'In transit' }}</span></td><td class="p-4">{{ app(\App\Services\Display::class)->dateTime($order['EstimatedDeliveryDate'] ?? null) }}</td><td class="p-4">{{ $order['DeliveryAddress']['ContactName'] ?? '—' }}</td><td class="p-4">{{ app(\App\Services\Display::class)->flag($order['DeliveryAddress'] ?? []) }}</td><td class="p-4">@if(app(\App\Services\Parcel2Go::class)->labelHash($order) && ! empty($order['OrderLineId']))<a class="font-semibold text-brand hover:underline" href="{{ route('shipping.label', $order['OrderLineId']) }}">Download PDF</a>@else<span class="text-slate-500">Unavailable</span>@endif</td></tr>
<tr><td class="p-4">{{ $order['OrderLineId'] ?? '—' }}</td><td class="p-4">{{ $order['Courier'] ?? '—' }}</td><td class="p-4">{{ $order['Service'] ?? '—' }}</td><td class="p-4"><span @class(['rounded-full px-2 py-1 text-xs font-semibold', 'bg-emerald-500/10 text-emerald-300' => $order['Tracking']['Delivered'] ?? false, 'bg-sky-500/10 text-sky-300' => ! ($order['Tracking']['Delivered'] ?? false)])>{{ ($order['Tracking']['Delivered'] ?? false) ? 'Delivered' : 'In transit' }}</span></td><td class="p-4">{{ app(\App\Services\Display::class)->dateTime($order['EstimatedDeliveryDate'] ?? null) }}</td><td class="p-4">{{ $order['DeliveryAddress']['ContactName'] ?? '—' }}</td><td class="p-4">{{ app(\App\Services\Display::class)->flag($order['DeliveryAddress'] ?? []) }}</td><td class="p-4">@if(app(\App\Services\Parcel2Go::class)->labelHash($order) && ! empty($order['OrderLineId']))<span class="flex gap-3 font-semibold"><a class="text-brand hover:underline" href="{{ route('shipping.label', [$order['OrderLineId'], 'size' => '4x6']) }}">4×6</a><a class="text-brand hover:underline" href="{{ route('shipping.label', $order['OrderLineId']) }}">A4</a></span>@else<span class="text-slate-500">Unavailable</span>@endif</td></tr>
@empty<tr><td colspan="8" class="p-6 text-slate-400">{{ $historyAvailable ? 'No shipments in Parcel2Go account history.' : 'Shipment history is unavailable. Check the Client Credentials in Settings.' }}</td></tr>@endforelse
</tbody></table>
</section>@endsection
+15
View File
@@ -210,6 +210,21 @@ class IntegrationsTest extends TestCase
Http::assertSent(fn ($request) => str_contains($request->url(), '/labels/123') && str_contains($request->url(), 'hash=link%2Bhash%3D'));
}
public function test_shipping_label_can_be_requested_in_4x6_format(): void
{
Http::preventStrayRequests();
Http::fake([
'https://auth.example.test/token' => Http::response(['access_token' => 'test-token']),
'https://shipping.example.test/api/me/orders/detail' => Http::response(['Orders' => [['OrderLineId' => 123, 'Hash' => 'order-hash']]]),
'https://shipping.example.test/api/labels/123*' => Http::response(['Base64EncodedLabels' => [base64_encode('%PDF-1.4 test label')]]),
]);
config()->set('services.parcel2go', ['client_id' => 'id', 'client_secret' => 'secret', 'auth_url' => 'https://auth.example.test/token', 'base_url' => 'https://shipping.example.test/api']);
$this->actingAs(User::factory()->create(['role' => 'admin']))->get(route('shipping.label', [123, 'size' => '4x6']))
->assertOk()->assertHeader('content-disposition', 'attachment; filename="parcel2go-123-4x6.pdf"');
Http::assertSent(fn ($request) => str_contains($request->url(), '/labels/123') && str_contains($request->url(), 'labelMedia=Label4x6'));
}
public function test_collection_booking_uses_quoted_service_and_available_date(): void
{
$this->pendingEtsyOrder();