fix(checkout): SO creation falls back to generic item if a catalog Item is missing

Tracing Mitchell's batch, SO creation 404'd on a missing ERPNext Item
(INTRASTATE-AUTHORITY) -- 30 of 70 catalog erpnext_item codes were missing in
ERPNext. Created all 30. Added a safety net: if createResource('Sales Order')
404s on a missing Item, retry once with every line remapped to the generic
COMPLIANCE-SERVICE item so a missing catalog Item never strands a paid order's SO.
This commit is contained in:
justin 2026-06-09 14:50:06 -05:00
parent e2467752dc
commit 8d301a1ab7

View file

@ -348,6 +348,27 @@ export async function ensureComplianceSalesOrder(
custom_surcharge_pct: surchargePct, custom_surcharge_pct: surchargePct,
workflow_state: "Received", workflow_state: "Received",
items: lineItems, items: lineItems,
}).catch(async (e: unknown) => {
// Resilience: if a service's ERPNext Item is missing, the SO would 404.
// Retry once with every line item remapped to the generic COMPLIANCE-SERVICE
// item so a missing catalog Item never strands a paid order's SO. (The
// catalog Item should still be created; this is a safety net.)
const msg = String((e as { body?: { _server_messages?: string } })?.body?._server_messages || e);
if (/not found/i.test(msg)) {
console.warn(`[checkout] SO item missing for ${orderId}, retrying with generic item:`, msg.slice(0, 120));
const fallback = lineItems.map(li => ({ ...li, item_code: "COMPLIANCE-SERVICE" }));
return createResource("Sales Order", {
customer: erpnextCustomer,
delivery_date: new Date(Date.now() + 30 * 86400000).toISOString().split("T")[0],
custom_external_order_id: orderId,
custom_order_type: "compliance",
custom_payment_gateway: GATEWAY_LABELS[paymentMethod] || paymentMethod,
custom_surcharge_pct: surchargePct,
workflow_state: "Received",
items: fallback,
});
}
throw e;
})) as { name: string }; })) as { name: string };
try { try {