From e23f204b7ca0f195e36fef2ba0bae7a686b8da4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frane=20Poli=C4=87?= <16856471+fPolic@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:54:20 +0100 Subject: [PATCH] fix(dashboard, core-flows, medusa): prevent creation of empty fulfillments (#11664) --- .changeset/violet-carrots-unite.md | 7 ++++++ .../order-create-fulfillment-form.tsx | 25 ++++++++++++------- .../src/order/workflows/create-fulfillment.ts | 7 ++++++ .../medusa/src/api/admin/orders/validators.ts | 2 +- 4 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 .changeset/violet-carrots-unite.md diff --git a/.changeset/violet-carrots-unite.md b/.changeset/violet-carrots-unite.md new file mode 100644 index 0000000000..ea04031677 --- /dev/null +++ b/.changeset/violet-carrots-unite.md @@ -0,0 +1,7 @@ +--- +"@medusajs/dashboard": patch +"@medusajs/core-flows": patch +"@medusajs/medusa": patch +--- + +fix(core-flows, dashboard, medusa): prevent creatiion of a fulfilment without items diff --git a/packages/admin/dashboard/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-form.tsx b/packages/admin/dashboard/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-form.tsx index 4424851f37..ec5a49545f 100644 --- a/packages/admin/dashboard/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-form.tsx +++ b/packages/admin/dashboard/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-form.tsx @@ -122,19 +122,26 @@ export function OrderCreateFulfillmentForm({ {} as Record ) + const items = Object.entries(data.quantity) + .filter( + ([id, value]) => + !!value && itemShippingProfileMap[id] === selectedShippingProfileId + ) + .map(([id, quantity]) => ({ + id, + quantity, + })) + + if (!items.length) { + toast.error(t("orders.fulfillment.error.noItems")) + return + } + const payload: HttpTypes.AdminCreateOrderFulfillment = { location_id: selectedLocationId, shipping_option_id: shippingOptionId, no_notification: !data.send_notification, - items: Object.entries(data.quantity) - .filter( - ([id, value]) => - !!value && itemShippingProfileMap[id] === selectedShippingProfileId - ) - .map(([id, quantity]) => ({ - id, - quantity, - })), + items, } try { diff --git a/packages/core/core-flows/src/order/workflows/create-fulfillment.ts b/packages/core/core-flows/src/order/workflows/create-fulfillment.ts index 17af74f648..4a764fa07d 100644 --- a/packages/core/core-flows/src/order/workflows/create-fulfillment.ts +++ b/packages/core/core-flows/src/order/workflows/create-fulfillment.ts @@ -83,6 +83,13 @@ export type CreateFulfillmentValidateOrderStepInput = { export const createFulfillmentValidateOrder = createStep( "create-fulfillment-validate-order", ({ order, inputItems }: CreateFulfillmentValidateOrderStepInput) => { + if (!inputItems.length) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + "No items to fulfill" + ) + } + throwIfOrderIsCancelled({ order }) throwIfItemsDoesNotExistsInOrder({ order, inputItems }) throwIfItemsAreNotGroupedByShippingRequirement({ order, inputItems }) diff --git a/packages/medusa/src/api/admin/orders/validators.ts b/packages/medusa/src/api/admin/orders/validators.ts index 88abafefad..98c0754bd2 100644 --- a/packages/medusa/src/api/admin/orders/validators.ts +++ b/packages/medusa/src/api/admin/orders/validators.ts @@ -71,7 +71,7 @@ export type AdminOrderCreateFulfillmentType = z.infer< typeof OrderCreateFulfillment > export const OrderCreateFulfillment = z.object({ - items: z.array(Item), + items: z.array(Item).min(1), location_id: z.string().nullish(), shipping_option_id: z.string().optional(), no_notification: z.boolean().optional(),