Skip to content

Commit fea3d4e

Browse files
authored
fix(core-flows): Access orderItem.variant safely inside convertDraftOrderWorkflow when containing custom items (#14233)
* Access orderItem variant safely on convert draft order workflow * Tests * Add changest * Remove .only from test
1 parent b53d63d commit fea3d4e

File tree

3 files changed

+105
-2
lines changed

3 files changed

+105
-2
lines changed

.changeset/three-dodos-admire.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@medusajs/core-flows": patch
3+
---
4+
5+
fix(core-flows): Access orderItem.variant safely inside convertDraftOrderWorkflow when containing custom items

integration-tests/http/__tests__/draft-order/admin/draft-order.spec.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,102 @@ medusaIntegrationTestRunner({
416416
expect(response.status).toBe(200)
417417
expect(response.data.order.status).toBe("pending")
418418
})
419+
420+
it("should convert a draft order with a custom item (without variant_id) to an order", async () => {
421+
await api.post(
422+
`/admin/draft-orders/${testDraftOrder.id}/edit`,
423+
{},
424+
adminHeaders
425+
)
426+
427+
await api.post(
428+
`/admin/draft-orders/${testDraftOrder.id}/edit/items`,
429+
{
430+
items: [
431+
{
432+
title: "Custom Item",
433+
quantity: 2,
434+
unit_price: 1500,
435+
},
436+
],
437+
},
438+
adminHeaders
439+
)
440+
441+
await api.post(
442+
`/admin/draft-orders/${testDraftOrder.id}/edit/confirm`,
443+
{},
444+
adminHeaders
445+
)
446+
447+
const response = await api.post(
448+
`/admin/draft-orders/${testDraftOrder.id}/convert-to-order`,
449+
{},
450+
adminHeaders
451+
)
452+
453+
expect(response.status).toBe(200)
454+
expect(response.data.order.status).toBe("pending")
455+
})
456+
457+
it("should convert a draft order with both variant items and custom items to an order", async () => {
458+
await api.post(
459+
`/admin/draft-orders/${testDraftOrder.id}/edit`,
460+
{},
461+
adminHeaders
462+
)
463+
464+
await api.post(
465+
`/admin/draft-orders/${testDraftOrder.id}/edit/items`,
466+
{
467+
items: [
468+
{
469+
variant_id: product.variants.find((v) => v.title === "L shirt")
470+
.id,
471+
quantity: 1,
472+
},
473+
{
474+
title: "Custom Item",
475+
quantity: 1,
476+
unit_price: 2000,
477+
},
478+
],
479+
},
480+
adminHeaders
481+
)
482+
483+
await api.post(
484+
`/admin/draft-orders/${testDraftOrder.id}/edit/confirm`,
485+
{},
486+
adminHeaders
487+
)
488+
489+
let reservations = (await api.get(`/admin/reservations`, adminHeaders))
490+
.data.reservations
491+
492+
expect(reservations.length).toBe(0)
493+
494+
const response = await api.post(
495+
`/admin/draft-orders/${testDraftOrder.id}/convert-to-order`,
496+
{},
497+
adminHeaders
498+
)
499+
500+
reservations = (await api.get(`/admin/reservations`, adminHeaders)).data
501+
.reservations
502+
503+
expect(reservations).toEqual(
504+
expect.arrayContaining([
505+
expect.objectContaining({
506+
inventory_item_id: inventoryItemLarge.id,
507+
quantity: 1,
508+
}),
509+
])
510+
)
511+
512+
expect(response.status).toBe(200)
513+
expect(response.data.order.status).toBe("pending")
514+
})
419515
})
420516

421517
describe("POST /draft-orders/:id/edit/items/:item_id", () => {

packages/core/core-flows/src/draft-order/workflows/convert-draft-order.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,13 @@ export const convertDraftOrderWorkflow = createWorkflow(
143143

144144
for (const orderItem of orderItems.items ?? []) {
145145
items.push({
146-
variant_id: orderItem.variant.id,
146+
variant_id: orderItem.variant?.id,
147147
quantity: orderItem.quantity,
148148
id: orderItem.id,
149149
})
150-
variants.push(orderItem.variant)
150+
if (orderItem.variant) {
151+
variants.push(orderItem.variant)
152+
}
151153
}
152154

153155
return {

0 commit comments

Comments
 (0)