feat(invoice): add Shopify order #, shipping address/method/cost and tracking

- Query Order.shippingLine and Order.fulfillments.trackingInfo from Admin GraphQL.
- Surface orderName (#1004) so customers recognise their order alongside the sequential invoice number.
- Render shipping cost as a synthetic line item (folds into the VAT breakdown).
- Show shipping method (Versandart / Shipping method) and tracking numbers (clickable when URL present) in the meta block.
- Render a separate delivery-address block when the shipping address differs from billing.
- DE strings stay informal (Versandart / Sendungsnummer / Lieferadresse / Versand).
This commit is contained in:
Gerhard Scheikl
2026-05-15 13:41:53 +02:00
parent 55a0dd03f2
commit 8780b4a68a
7 changed files with 345 additions and 16 deletions
@@ -56,6 +56,18 @@ const styles = StyleSheet.create({
fontFamily: "Helvetica-Bold",
fontSize: 10,
},
shippingAddressBlock: {
marginTop: 10,
paddingTop: 6,
borderTopWidth: 0.5,
borderTopColor: TABLE_BORDER,
},
shippingAddressHeading: {
fontFamily: "Helvetica-Bold",
color: BRAND_BLUE,
fontSize: 8,
marginBottom: 2,
},
metaBlock: {
width: "40%",
},
@@ -264,6 +276,12 @@ export function InvoiceDocument({ invoice }: DocProps) {
<View style={styles.recipientBlock}>
<Text style={styles.senderLine}>{senderInline(invoice.issuer)}</Text>
<Recipient recipient={invoice.recipient} />
{invoice.separateShippingAddress ? (
<View style={styles.shippingAddressBlock}>
<Text style={styles.shippingAddressHeading}>{t.shippingAddressHeading}</Text>
<Recipient recipient={invoice.separateShippingAddress} />
</View>
) : null}
</View>
<View style={styles.metaBlock}>
<View style={styles.metaTable}>
@@ -271,6 +289,12 @@ export function InvoiceDocument({ invoice }: DocProps) {
<Text style={styles.metaLabel}>{invoice.kind === "offer" ? t.offerNumber : t.invoiceNumber}</Text>
<Text style={styles.invoiceNumberBig}>{invoice.number}</Text>
</View>
{invoice.kind === "invoice" && invoice.orderName ? (
<View style={styles.metaRow}>
<Text style={styles.metaLabel}>{t.orderNumberLabel}</Text>
<Text style={styles.metaValue}>{invoice.orderName}</Text>
</View>
) : null}
<View style={styles.metaRow}>
<Text style={styles.metaLabel}>{invoice.kind === "offer" ? t.offerDate : t.invoiceDate}</Text>
<Text style={styles.metaValue}>{formatDate(invoice.invoiceDate, invoice.language)}</Text>
@@ -303,6 +327,25 @@ export function InvoiceDocument({ invoice }: DocProps) {
</Text>
</View>
)}
{invoice.kind === "invoice" && invoice.shippingMethod ? (
<View style={styles.metaRow}>
<Text style={styles.metaLabel}>{t.shippingMethodLabel}</Text>
<Text style={styles.metaValue}>{invoice.shippingMethod}</Text>
</View>
) : null}
{invoice.kind === "invoice" && invoice.tracking.map((tr) => (
<View key={tr.number} style={styles.metaRow}>
<Text style={styles.metaLabel}>
{t.trackingLabel}
{tr.company ? ` (${tr.company})` : ""}
</Text>
{tr.url ? (
<Link src={tr.url} style={styles.metaValue}>{tr.number}</Link>
) : (
<Text style={styles.metaValue}>{tr.number}</Text>
)}
</View>
))}
</View>
</View>
</View>