/** * GET /api/accounting/amazon-ads/document?invoiceNo=…[&download=1] * Streams the original Amazon PDF: local cache first, otherwise downloaded from * the Ads API (and cached), otherwise — with &cInvoiceId= — the ORIGINAL PDF attached to * the iDempiere document (Strapi, PO_Invoice). The last fallback is what makes the page * independent of the local store: a booked invoice always has its PDF on the document. */ import { isAdsApiConnected, downloadAdsInvoicePdf } from '../../../utils/amazonAds/adsApi' import { getInvoice, readInvoicePdf, upsertInvoice } from '../../../utils/amazonAds/invoiceStore' import { orgIdOf } from '../../../utils/amazonAds/routeShared' import getTokenHelper from '../../../utils/getTokenHelper' import { findInvoiceOriginalPdf } from '../../../utils/invoiceOriginalPdf' export default defineEventHandler(async (event) => { const q = getQuery(event) const no = String(q.invoiceNo || '').trim() if (!no) { setResponseStatus(event, 400); return { status: 400, message: 'invoiceNo fehlt' } } const token = await getTokenHelper(event) let row: any = null let pdf: Buffer | null = null try { row = await getInvoice(event, token, no); pdf = await readInvoicePdf(event, token, row) } catch (e: any) { console.warn('[AmazonAds] store lookup failed:', e?.data?.detail || e?.message || e) } let name = row?.pdfName || `INVOICE-${no}.pdf` if (!pdf && row?.invoice && isAdsApiConnected(event)) { try { const doc = await downloadAdsInvoicePdf(event, no, 'INVOICE') if (doc) { pdf = doc.buffer; name = doc.fileName; try { await upsertInvoice(event, token, orgIdOf(event), row.invoice, { pdf, pdfName: name }) } catch {} } } catch (e: any) { setResponseStatus(event, 502); return { status: 502, message: e?.message || String(e) } } } const cInvoiceId = Number(q.cInvoiceId || 0) if (!pdf && cInvoiceId) { try { const orig = await findInvoiceOriginalPdf(event, cInvoiceId) if (orig?.buffer?.length) { pdf = orig.buffer; name = orig.fileName || name } } catch (e: any) { console.warn('[AmazonAds] attachment lookup failed:', e?.message || e) } } if (!pdf) { setResponseStatus(event, 404); return { status: 404, message: 'Kein PDF für diese Rechnung vorhanden' } } setHeader(event, 'Content-Type', 'application/pdf') setHeader(event, 'Content-Disposition', `${q.download ? 'attachment' : 'inline'}; filename="${name.replace(/[^A-Za-z0-9._-]/g, '_')}"`) setHeader(event, 'Cache-Control', 'private, max-age=300') return pdf })