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
+34 -10
View File
@@ -137,6 +137,7 @@ function buildAtB2BOrder(): RawOrderForInvoice {
paymentGatewayNames: ["manual"],
taxesIncluded: false,
discountCodes: [],
deliveryMethods: [],
customer: {
firstName: "Lukas",
lastName: "Schmidhofer",
@@ -306,6 +307,10 @@ function buildPickupOrder(): RawOrderForInvoice {
discountedPriceSet: { shopMoney: { amount: "0.00", currencyCode: "EUR" } },
taxLines: [],
};
// Primary signal — what Shopify Local Pickup actually populates.
o.deliveryMethods = [
{ methodType: "PICK_UP", locationName: "Lager Graz" },
];
return o;
}
@@ -593,26 +598,45 @@ async function main() {
settings: settings as never,
invoiceNumber: "RE-1030",
});
assert("isPickup detected", pickupVm.isPickup);
assertEq("shippingMethod replaced with localized label", pickupVm.shippingMethod, "Abholung");
assert("isPickup detected via DeliveryMethodType=PICK_UP", pickupVm.isPickup);
assertEq("pickupLocationName propagated", pickupVm.pickupLocationName, "Lager Graz");
assert("shippingMethod cleared for pickup (renderer uses pickup row instead)",
pickupVm.shippingMethod == null);
assert(
"separateShippingAddress suppressed for pickup",
pickupVm.separateShippingAddress == null,
);
pickupVm.issuer.logoDataUrl = vm.issuer.logoDataUrl;
const pickupText = await pdfToText(await renderInvoicePdf(pickupVm));
assert("DE pickup PDF shows 'Abholort' label", pickupText.includes("Abholort"));
assert("DE pickup PDF shows location name", pickupText.includes("Lager Graz"));
assert("DE pickup PDF does NOT show 'Versandart'", !pickupText.includes("Versandart"));
assert(
"DE pickup PDF does NOT render pickup-location address as delivery address",
!pickupText.includes("Lieferadresse"),
);
// Shopify-Local-Pickup-app fallback: methodType missing but shippingLine
// is named "Pickup at …".
const legacyPickupOrder = buildPickupOrder();
legacyPickupOrder.deliveryMethods = [];
const legacyPickupVm = composeInvoice({
order: legacyPickupOrder,
settings: settings as never,
invoiceNumber: "RE-1032",
});
assert("legacy heuristic still detects pickup from shippingLine", legacyPickupVm.isPickup);
// EN translation
const pickupEnVm = composeInvoice({
order: pickupOrder,
settings: settings as never,
invoiceNumber: "RE-1031",
forceLanguage: "en",
});
assertEq("pickup label EN", pickupEnVm.shippingMethod, "Pick-up");
pickupVm.issuer.logoDataUrl = vm.issuer.logoDataUrl;
const pickupText = await pdfToText(await renderInvoicePdf(pickupVm));
assert("DE pickup PDF shows 'Abholung'", pickupText.includes("Abholung"));
assert(
"DE pickup PDF does NOT render pickup-location address as delivery address",
!pickupText.includes("Lieferadresse"),
);
pickupEnVm.issuer.logoDataUrl = vm.issuer.logoDataUrl;
const pickupEnText = await pdfToText(await renderInvoicePdf(pickupEnVm));
assert("EN pickup PDF shows 'Pick-up location' label", pickupEnText.includes("Pick-up location"));
// Fallback: when footerNoteEn is empty, English uses the German note.
console.log("• Footer note fallback (en → de when EN empty)");