fix(order): ignore reservation when manage_inventory is false (#7594)
This commit is contained in:
committed by
GitHub
parent
0929c4f457
commit
68fb04b849
@@ -96,6 +96,11 @@ async function prepareDataFixtures({ container }) {
|
||||
title: "Test variant",
|
||||
sku: "test-variant",
|
||||
},
|
||||
{
|
||||
title: "Test variant no inventory management",
|
||||
sku: "test-variant-no-inventory",
|
||||
manage_inventory: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
@@ -228,7 +233,15 @@ async function createOrderFixture({ container, product, location }) {
|
||||
provider_id: "coupon_kings",
|
||||
},
|
||||
],
|
||||
} as any,
|
||||
},
|
||||
{
|
||||
title: product.title,
|
||||
variant_sku: product.variants[1].sku,
|
||||
variant_title: product.variants[1].title,
|
||||
variant_id: product.variants[1].id,
|
||||
quantity: 1,
|
||||
unit_price: 200,
|
||||
},
|
||||
],
|
||||
transactions: [
|
||||
{
|
||||
@@ -282,6 +295,7 @@ async function createOrderFixture({ container, product, location }) {
|
||||
})
|
||||
|
||||
const inventoryModule = container.resolve(ModuleRegistrationName.INVENTORY)
|
||||
|
||||
const reservation = await inventoryModule.createReservationItems([
|
||||
{
|
||||
line_item_id: order.items![0].id,
|
||||
@@ -429,6 +443,81 @@ medusaIntegrationTestRunner({
|
||||
])
|
||||
expect(stockAvailabilityAfterCancelled).toEqual(2)
|
||||
})
|
||||
|
||||
it("should revert an order fulfillment when it fails and recreate it when tried again", async () => {
|
||||
const order = await createOrderFixture({ container, product, location })
|
||||
|
||||
// Create a fulfillment
|
||||
const createOrderFulfillmentData: OrderWorkflow.CreateOrderFulfillmentWorkflowInput =
|
||||
{
|
||||
order_id: order.id,
|
||||
created_by: "user_1",
|
||||
items: [
|
||||
{
|
||||
id: order.items![0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
no_notification: false,
|
||||
location_id: undefined,
|
||||
}
|
||||
|
||||
const worflow = createOrderFulfillmentWorkflow(container)
|
||||
worflow.addAction("fail", {
|
||||
invoke: () => {
|
||||
throw new Error("Fulfillment failed")
|
||||
},
|
||||
})
|
||||
|
||||
await worflow
|
||||
.run({
|
||||
input: createOrderFulfillmentData,
|
||||
})
|
||||
.catch(() => void 0)
|
||||
|
||||
worflow.deleteAction("fail")
|
||||
|
||||
await worflow.run({
|
||||
input: createOrderFulfillmentData,
|
||||
})
|
||||
|
||||
const remoteQuery = container.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "order",
|
||||
variables: {
|
||||
id: order.id,
|
||||
},
|
||||
fields: [
|
||||
"*",
|
||||
"items.*",
|
||||
"shipping_methods.*",
|
||||
"total",
|
||||
"item_total",
|
||||
"fulfillments.*",
|
||||
],
|
||||
})
|
||||
|
||||
const [orderFulfill] = await remoteQuery(remoteQueryObject)
|
||||
|
||||
expect(orderFulfill.fulfillments).toHaveLength(1)
|
||||
expect(orderFulfill.items[0].detail.fulfilled_quantity).toEqual(1)
|
||||
|
||||
const inventoryModule = container.resolve(
|
||||
ModuleRegistrationName.INVENTORY
|
||||
)
|
||||
const reservation = await inventoryModule.listReservationItems({
|
||||
line_item_id: order.items![0].id,
|
||||
})
|
||||
expect(reservation).toHaveLength(0)
|
||||
|
||||
const stockAvailability = await inventoryModule.retrieveStockedQuantity(
|
||||
inventoryItem.id,
|
||||
[location.id]
|
||||
)
|
||||
expect(stockAvailability).toEqual(1)
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -94,7 +94,7 @@ function prepareFulfillmentData({
|
||||
const reservation = reservationItemMap.get(i.id)!
|
||||
return {
|
||||
line_item_id: i.id,
|
||||
inventory_item_id: reservation.inventory_item_id,
|
||||
inventory_item_id: reservation?.inventory_item_id,
|
||||
quantity: i.quantity,
|
||||
title: orderItem.variant_title ?? orderItem.title,
|
||||
sku: orderItem.variant_sku || "",
|
||||
@@ -114,6 +114,9 @@ function prepareFulfillmentData({
|
||||
)
|
||||
}
|
||||
|
||||
const shippingAddress = order.shipping_address ?? { id: undefined }
|
||||
delete shippingAddress.id
|
||||
|
||||
return {
|
||||
input: {
|
||||
location_id: locationId,
|
||||
@@ -121,18 +124,12 @@ function prepareFulfillmentData({
|
||||
shipping_option_id: shippingOption.id,
|
||||
items: fulfillmentItems,
|
||||
labels: [] as FulfillmentWorkflow.CreateFulfillmentLabelWorkflowDTO[], // TODO: shipping labels
|
||||
delivery_address: order.shipping_address ?? ({} as any),
|
||||
delivery_address: shippingAddress as any,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function prepareInventoryUpdate({ reservations, order, input }) {
|
||||
if (!reservations || !reservations.length) {
|
||||
throw new Error(
|
||||
`No stock reservation found for items ${input.items.map((i) => i.id)}`
|
||||
)
|
||||
}
|
||||
|
||||
const reservationMap = reservations.reduce((acc, reservation) => {
|
||||
acc[reservation.line_item_id as string] = reservation
|
||||
return acc
|
||||
@@ -157,6 +154,15 @@ function prepareInventoryUpdate({ reservations, order, input }) {
|
||||
|
||||
for (const item of order.items) {
|
||||
const reservation = reservationMap[item.id]
|
||||
if (!reservation) {
|
||||
if (item.manage_inventory) {
|
||||
throw new Error(
|
||||
`No stock reservation found for item ${item.id} - ${item.title} (${item.variant_title})`
|
||||
)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
const inputQuantity = inputItemsMap[item.id]?.quantity ?? item.quantity
|
||||
|
||||
const quantity = reservation.quantity - inputQuantity
|
||||
@@ -199,6 +205,7 @@ export const createOrderFulfillmentWorkflow = createWorkflow(
|
||||
"region_id",
|
||||
"currency_code",
|
||||
"items.*",
|
||||
"items.variant.manage_inventory",
|
||||
"shipping_address.*",
|
||||
"shipping_methods.shipping_option_id", // TODO: which shipping method to use when multiple?
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user