fix(core-flows, dashboard): inventory kit reservations (#9502)

**What**
- fix `prepareConfirmInventory` to account for inventory kit items
  - _note: this step is reused in the complete cart and all RMA flows_ 
- properly remove reservations for items that are removed from the order edit
- invalidate inventory/reservations cache when order edit is confirmed

---

https://github.com/user-attachments/assets/f12e9198-0718-4c08-bd81-efc536eca146

---

FIXES CC-565
This commit is contained in:
Frane Polić authored and GitHub committed 2024-10-09 17:54:35 +00:00
1 parent 7f1f075222
commit 1b9379be62
6 files changed
+37 -10

No files matched your search

@@ -6,6 +6,8 @@ import { sdk } from "../../lib/client"
import { queryClient } from "../../lib/query-client" import { queryClient } from "../../lib/query-client"
import { ordersQueryKeys } from "./orders" import { ordersQueryKeys } from "./orders"
import { FetchError } from "@medusajs/js-sdk" import { FetchError } from "@medusajs/js-sdk"
import { reservationItemsQueryKeys } from "./reservations"
import { inventoryItemsQueryKeys } from "./inventory.tsx"
export const useCreateOrderEdit = ( export const useCreateOrderEdit = (
orderId: string, orderId: string,
@@ -82,6 +84,19 @@ export const useConfirmOrderEdit = (
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: ordersQueryKeys.changes(id), queryKey: ordersQueryKeys.changes(id),
}) })
queryClient.invalidateQueries({
queryKey: reservationItemsQueryKeys.lists(),
})
queryClient.invalidateQueries({
queryKey: inventoryItemsQueryKeys.lists(),
})
queryClient.invalidateQueries({
queryKey: inventoryItemsQueryKeys.details(),
})
options?.onSuccess?.(data, variables, context) options?.onSuccess?.(data, variables, context)
}, },
...options, ...options,
@@ -1,4 +1,4 @@
import { IInventoryService } from "@medusajs/framework/types" import { BigNumberInput, IInventoryService } from "@medusajs/framework/types"
import { import {
MathBN, MathBN,
MedusaError, MedusaError,
@@ -12,7 +12,7 @@ export interface ConfirmVariantInventoryStepInput {
inventory_item_id: string inventory_item_id: string
required_quantity: number required_quantity: number
allow_backorder: boolean allow_backorder: boolean
quantity: number quantity: BigNumberInput
location_ids: string[] location_ids: string[]
}[] }[]
} }
@@ -1,6 +1,7 @@
import { IInventoryService } from "@medusajs/framework/types" import { IInventoryService } from "@medusajs/framework/types"
import { MathBN, Modules } from "@medusajs/framework/utils" import { MathBN, Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { BigNumberInput } from "@medusajs/types"
export interface ReserveVariantInventoryStepInput { export interface ReserveVariantInventoryStepInput {
items: { items: {
@@ -8,7 +9,7 @@ export interface ReserveVariantInventoryStepInput {
inventory_item_id: string inventory_item_id: string
required_quantity: number required_quantity: number
allow_backorder: boolean allow_backorder: boolean
quantity: number quantity: BigNumberInput
location_ids: string[] location_ids: string[]
}[] }[]
} }
@@ -28,7 +28,7 @@ interface ConfirmInventoryItem {
inventory_item_id: string inventory_item_id: string
required_quantity: number required_quantity: number
allow_backorder: boolean allow_backorder: boolean
quantity: number quantity: BigNumberInput
location_ids: string[] location_ids: string[]
} }
@@ -143,25 +143,27 @@ const formatInventoryInput = ({
return return
} }
const variantInventoryItem = product_variant_inventory_items.find( const variantInventoryItems = product_variant_inventory_items.filter(
(i) => i.variant_id === item.variant_id (i) => i.variant_id === item.variant_id
) )
if (!variantInventoryItem) { if (!variantInventoryItems.length) {
throw new MedusaError( throw new MedusaError(
MedusaError.Types.INVALID_DATA, MedusaError.Types.INVALID_DATA,
`Variant ${item.variant_id} does not have any inventory items associated with it.` `Variant ${item.variant_id} does not have any inventory items associated with it.`
) )
} }
variantInventoryItems.forEach((variantInventoryItem) =>
itemsToConfirm.push({ itemsToConfirm.push({
id: item.id, id: item.id,
inventory_item_id: variantInventoryItem.inventory_item_id, inventory_item_id: variantInventoryItem.inventory_item_id,
required_quantity: variantInventoryItem.required_quantity, required_quantity: variantInventoryItem.required_quantity,
allow_backorder: !!variant.allow_backorder, allow_backorder: !!variant.allow_backorder,
quantity: item.quantity as number, // TODO: update type to BigNumberInput quantity: item.quantity,
location_ids: location_ids, location_ids: location_ids,
}) })
)
}) })
return itemsToConfirm return itemsToConfirm
@@ -5,6 +5,7 @@ import {
createWorkflow, createWorkflow,
transform, transform,
} from "@medusajs/framework/workflows-sdk" } from "@medusajs/framework/workflows-sdk"
import { BigNumberInput } from "@medusajs/types"
import { confirmInventoryStep } from "../steps" import { confirmInventoryStep } from "../steps"
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input" import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
@@ -14,7 +15,7 @@ export interface ConfirmVariantInventoryWorkflowOutput {
inventory_item_id: string inventory_item_id: string
required_quantity: number required_quantity: number
allow_backorder: boolean allow_backorder: boolean
quantity: number quantity: BigNumberInput
location_ids: string[] location_ids: string[]
}[] }[]
} }
@@ -134,8 +134,16 @@ export const confirmOrderEditRequestWorkflow = createWorkflow(
throw_if_key_not_found: true, throw_if_key_not_found: true,
}).config({ name: "order-items-query" }) }).config({ name: "order-items-query" })
const lineItemIds = transform({ orderItems }, (data) => const lineItemIds = transform(
data.orderItems.items.map(({ id }) => id) { orderItems, previousOrderItems: order.items },
(data) => {
const previousItemIds = (data.previousOrderItems || []).map(
({ id }) => id
) // items that have been removed with the change
const newItemIds = data.orderItems.items.map(({ id }) => id)
return [...new Set([...previousItemIds, newItemIds])]
}
) )
deleteReservationsByLineItemsStep(lineItemIds) deleteReservationsByLineItemsStep(lineItemIds)