fix(order): ignore reservation when manage_inventory is false (#7594)

This commit is contained in:
Carlos R. L. Rodrigues
2024-06-04 07:08:54 -03:00
committed by GitHub
parent 0929c4f457
commit 68fb04b849
2 changed files with 105 additions and 9 deletions

View File

@@ -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)
})
})
},
})

View File

@@ -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?
],