- Add CachedOrder holdReasonCode/holdNote and ON_HOLD fulfillment status - Supplier UI: modal for hold reasons; vendor dashboard shows hold details - Sync to Shopify: native fulfillmentOrderHold (GraphQL) plus JUNO_ON_HOLD tag and juno.supplier_hold metafield; release holds when clearing - Preserve pending supplier fulfillment on webhook cache updates - Docker volume for gmail-reply-logos; settings note for API scopes Made-with: Cursor
44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
export type CanonicalFulfillmentStatus =
|
|
| "UNFULFILLED"
|
|
| "IN_PROGRESS"
|
|
| "ON_HOLD"
|
|
| "SHIPPED"
|
|
| "FULFILLED"
|
|
| "CANCELLED"
|
|
|
|
const SHOPIFY_FULFILLMENT_MAP: Record<CanonicalFulfillmentStatus, string> = {
|
|
UNFULFILLED: "unfulfilled",
|
|
IN_PROGRESS: "in_progress",
|
|
ON_HOLD: "on_hold",
|
|
SHIPPED: "shipped",
|
|
FULFILLED: "fulfilled",
|
|
CANCELLED: "cancelled",
|
|
}
|
|
|
|
export function normalizeFulfillmentStatus(input: string | null | undefined): CanonicalFulfillmentStatus {
|
|
const raw = String(input ?? "")
|
|
.trim()
|
|
.replace(/[\s-]+/g, "_")
|
|
.toUpperCase()
|
|
|
|
if (raw === "FULFILLED") return "FULFILLED"
|
|
if (raw === "SHIPPED") return "SHIPPED"
|
|
if (raw === "IN_PROGRESS" || raw === "INPROGRESS" || raw === "PARTIAL" || raw === "PARTIALLY_FULFILLED") {
|
|
return "IN_PROGRESS"
|
|
}
|
|
if (raw === "CANCELLED" || raw === "CANCELED") return "CANCELLED"
|
|
if (raw === "ON_HOLD" || raw === "ONHOLD" || raw === "HOLD" || raw === "PENDING_HOLD") {
|
|
return "ON_HOLD"
|
|
}
|
|
return "UNFULFILLED"
|
|
}
|
|
|
|
export function toVendorDisplayStatus(input: string | null | undefined): string {
|
|
return SHOPIFY_FULFILLMENT_MAP[normalizeFulfillmentStatus(input)]
|
|
}
|
|
|
|
export function isFulfilledLike(input: string | null | undefined): boolean {
|
|
return normalizeFulfillmentStatus(input) === "FULFILLED"
|
|
}
|
|
|