fix(invoice): detect pickup via DeliveryMethodType and show 'Abholort: <location>' meta row

- Use Order.fulfillmentOrders.deliveryMethod.methodType === 'PICK_UP' as the
  primary signal (Shopify Local Pickup app exposes this reliably; the
  shippingLine title is just the location name with no 'pickup' keyword).
  Keep the legacy shippingLine string heuristic as a fallback for custom
  shipping rates merchants name 'Abholung'/'Pickup'.
- Surface assignedLocation.name as pickupLocationName on the view model.
- Replace the 'Versandart: <location name>' row with 'Abholort: <location>'
  (DE) / 'Pick-up location: <location>' (EN); falls back to plain
  'Abholung'/'Pick-up' when the location name is unavailable.
This commit is contained in:
Gerhard Scheikl
2026-05-15 14:46:55 +02:00
parent 415a9dd462
commit d742e75419
7 changed files with 124 additions and 26 deletions
+32 -15
View File
@@ -62,10 +62,14 @@ export function composeInvoice({
});
let notices = deriveNotices({ order, settings, isB2B });
const isPickup = detectPickup(order.shippingLine);
const pickupInfo = detectPickup(order);
const isPickup = pickupInfo != null;
const separateShippingAddress = isPickup ? undefined : mapSeparateShippingAddress(order);
// For shipping orders we surface the carrier label (e.g. "Standardversand").
// For pickup orders the meta row uses a different label entirely
// ("Abholort: <location>") — see the renderer.
const shippingMethod = isPickup
? strings.pickupLabel
? undefined
: order.shippingLine?.title?.trim() || undefined;
const tracking = mapTracking(order);
@@ -135,6 +139,7 @@ export function composeInvoice({
tracking,
discountCodes: order.discountCodes ?? [],
isPickup,
pickupLocationName: pickupInfo?.locationName ?? undefined,
};
}
@@ -482,24 +487,36 @@ function mapTracking(order: RawOrderForInvoice): TrackingInfo[] {
}
/**
* Heuristically detects whether the order's shipping line is a "local
* pickup" line. Shopify exposes pickup either via the dedicated Local
* Pickup app (source contains "pickup") or via a custom rate the merchant
* named "Abholung"/"Pickup". When detected, callers should NOT render the
* Detects whether the order is a "local pickup" order. Primary signal is
* Shopify's `DeliveryMethodType` on the fulfillment order (`PICK_UP`),
* which is what the Shopify Local Pickup app sets. Falls back to a string
* heuristic on `shippingLine.source/code/title` for merchants who model
* pickup as a custom shipping rate named "Abholung"/"Pickup".
*
* Returns the pickup descriptor (with location name when known) or `null`
* when the order is a normal shipping order. Callers should not render the
* pickup-location address as a separate "delivery address".
*/
function detectPickup(shippingLine: RawShippingLine | null): boolean {
if (!shippingLine) return false;
const haystack = [
shippingLine.source,
shippingLine.code,
shippingLine.title,
shippingLine.carrierIdentifier,
]
function detectPickup(
order: RawOrderForInvoice,
): { locationName: string | null } | null {
// Primary: DeliveryMethodType from fulfillment orders.
for (const dm of order.deliveryMethods ?? []) {
if (dm.methodType === "PICK_UP") {
return { locationName: dm.locationName };
}
}
// Fallback: legacy string heuristic on shippingLine.
const sl = order.shippingLine;
if (!sl) return null;
const haystack = [sl.source, sl.code, sl.title, sl.carrierIdentifier]
.filter(Boolean)
.join(" ")
.toLowerCase();
return /pick[\s-]?up|abholung|abhol\b/.test(haystack);
if (/pick[\s-]?up|abholung|abhol\b/.test(haystack)) {
return { locationName: sl.title?.trim() || null };
}
return null;
}
/**