From 3307835e986bfecea33b0049ba55a5036e5b07f7 Mon Sep 17 00:00:00 2001 From: jeninh Date: Sat, 16 May 2026 22:32:07 -0400 Subject: [PATCH] fix(warehouse): correct label extension, surface print errors, revert status on carrier failure - Use .png extension for Chit Chats PNG labels (was hardcoded .pdf, breaking PDF readers) - Wrap QZ Tray qz.print() calls in try/catch and surface failures via labelErrors[orderId] - Revert warehouseOrder.status back to APPROVED if carrier throws after the SHIPPED claim, so retries don't hit "already shipped" 409 Co-Authored-By: Claude Opus 4.7 (1M context) --- .../api/fulfillment/get-label/+server.ts | 10 ++++++++ .../app/warehouse/fulfillment/+page.svelte | 23 +++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/resolution-frontend/src/routes/api/fulfillment/get-label/+server.ts b/resolution-frontend/src/routes/api/fulfillment/get-label/+server.ts index dc9a3e5..9369560 100644 --- a/resolution-frontend/src/routes/api/fulfillment/get-label/+server.ts +++ b/resolution-frontend/src/routes/api/fulfillment/get-label/+server.ts @@ -153,6 +153,7 @@ export const POST: RequestHandler = async (event) => { throw error(409, 'Order has already been shipped or is not in APPROVED status'); } + try { // Total weight always comes from items. Dimensions come from the packaging // record chosen at estimate time so the carrier request matches the quote. // Fall back to item-derived dims for legacy orders without packaging info. @@ -365,4 +366,13 @@ export const POST: RequestHandler = async (event) => { packingSlipBase64, shippingMethod }); + } catch (e) { + await db.update(warehouseOrder) + .set({ status: 'APPROVED', updatedAt: new Date() }) + .where(and( + eq(warehouseOrder.id, orderId), + eq(warehouseOrder.status, 'SHIPPED') + )); + throw e; + } }; diff --git a/resolution-frontend/src/routes/app/warehouse/fulfillment/+page.svelte b/resolution-frontend/src/routes/app/warehouse/fulfillment/+page.svelte index f8d4c92..ae5bf0e 100644 --- a/resolution-frontend/src/routes/app/warehouse/fulfillment/+page.svelte +++ b/resolution-frontend/src/routes/app/warehouse/fulfillment/+page.svelte @@ -38,6 +38,11 @@ return name || creator.email; } + function labelDownloadName(labelUrl: string | null, fulfillmentId: string | number): string { + const ext = labelUrl?.startsWith('data:image/png') ? 'png' : 'pdf'; + return `label-${fulfillmentId}.${ext}`; + } + const statuses = ['ESTIMATED', 'APPROVED', 'SHIPPED', 'CANCELLED']; const filteredOrders = $derived(() => { @@ -100,7 +105,7 @@ } catch { qzStatus = 'error'; } } - async function printAll(result: { labelUrl: string | null; packingSlipBase64: string }) { + async function printAll(orderId: string, result: { labelUrl: string | null; packingSlipBase64: string }) { if (!qz || qzStatus !== 'connected') return; const settings = getQZSettings(); if (!settings.printer) { alert('No printer selected. Go to Settings to configure.'); return; } @@ -113,7 +118,11 @@ if (result.labelUrl) { const base64Data = result.labelUrl.replace(/^data:(application\/pdf|image\/png);base64,/, ''); const format = result.labelUrl.startsWith('data:image/png') ? 'image' : 'pdf'; - await qz.print(config(), [{ type: 'pixel', format, flavor: 'base64', data: base64Data }]); + try { + await qz.print(config(), [{ type: 'pixel', format, flavor: 'base64', data: base64Data }]); + } catch (e: any) { + labelErrors[orderId] = `Label print failed: ${e?.message || e}`; + } } // Print packing slip @@ -121,7 +130,11 @@ const rawText = decodeURIComponent(escape(atob(result.packingSlipBase64))); const escapedText = rawText.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); const html = `
${escapedText}
`; - await qz.print(config(), [{ type: 'html', format: 'plain', data: html }]); + try { + await qz.print(config(), [{ type: 'html', format: 'plain', data: html }]); + } catch (e: any) { + labelErrors[orderId] = `Packing slip print failed: ${e?.message || e}`; + } } } @@ -311,14 +324,14 @@ {/if}
- {#if labelResults[order.id].labelUrl} 📥 Label {/if} {#if labelResults[order.id].packingSlipBase64}