fix(core-flows): confirm return request (#8242)
This commit is contained in:
1 parent
47dde05517
commit
f38f6d53b4
11 files changed
+190
-36
No files matched your search
@@ -9,7 +9,7 @@ jest.setTimeout(30000)
|
|||||||
|
|
||||||
medusaIntegrationTestRunner({
|
medusaIntegrationTestRunner({
|
||||||
testSuite: ({ dbConnection, getContainer, api }) => {
|
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||||
let order
|
let order, order2
|
||||||
let returnShippingOption
|
let returnShippingOption
|
||||||
let shippingProfile
|
let shippingProfile
|
||||||
let fulfillmentSet
|
let fulfillmentSet
|
||||||
@@ -80,6 +80,38 @@ medusaIntegrationTestRunner({
|
|||||||
customer_id: "joe",
|
customer_id: "joe",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
order2 = await orderModule.createOrders({
|
||||||
|
region_id: "test_region_id",
|
||||||
|
email: "foo@bar2.com",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Custom Iasdasd2",
|
||||||
|
quantity: 1,
|
||||||
|
unit_price: 20,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sales_channel_id: "test",
|
||||||
|
shipping_address: {
|
||||||
|
first_name: "Test",
|
||||||
|
last_name: "Test",
|
||||||
|
address_1: "Test",
|
||||||
|
city: "Test",
|
||||||
|
country_code: "US",
|
||||||
|
postal_code: "12345",
|
||||||
|
phone: "12345",
|
||||||
|
},
|
||||||
|
billing_address: {
|
||||||
|
first_name: "Test",
|
||||||
|
last_name: "Test",
|
||||||
|
address_1: "Test",
|
||||||
|
city: "Test",
|
||||||
|
country_code: "US",
|
||||||
|
postal_code: "12345",
|
||||||
|
},
|
||||||
|
currency_code: "usd",
|
||||||
|
customer_id: "joe",
|
||||||
|
})
|
||||||
|
|
||||||
shippingProfile = (
|
shippingProfile = (
|
||||||
await api.post(
|
await api.post(
|
||||||
`/admin/shipping-profiles`,
|
`/admin/shipping-profiles`,
|
||||||
@@ -171,9 +203,107 @@ medusaIntegrationTestRunner({
|
|||||||
},
|
},
|
||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/orders/${order2.id}/fulfillments`,
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: order2.items[0].id,
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("Returns lifecycle", () => {
|
describe("Returns lifecycle", () => {
|
||||||
|
it("Full flow with 2 orders", async () => {
|
||||||
|
let result = await api.post(
|
||||||
|
"/admin/returns",
|
||||||
|
{
|
||||||
|
order_id: order.id,
|
||||||
|
description: "Test",
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
let r2 = await api.post(
|
||||||
|
"/admin/returns",
|
||||||
|
{
|
||||||
|
order_id: order2.id,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
const returnId2 = r2.data.return.id
|
||||||
|
const item2 = order2.items[0]
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/returns/${returnId2}/request-items`,
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: item2.id,
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
await api.post(
|
||||||
|
`/admin/returns/${returnId2}/shipping-method`,
|
||||||
|
{
|
||||||
|
shipping_option_id: returnShippingOption.id,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
await api.post(`/admin/returns/${returnId2}/request`, {}, adminHeaders)
|
||||||
|
|
||||||
|
const returnId = result.data.return.id
|
||||||
|
|
||||||
|
const item = order.items[0]
|
||||||
|
|
||||||
|
result = await api.post(
|
||||||
|
`/admin/returns/${returnId}/request-items`,
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: item.id,
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/returns/${returnId}/shipping-method`,
|
||||||
|
{
|
||||||
|
shipping_option_id: returnShippingOption.id,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
// updated the requested quantitty
|
||||||
|
const updateReturnItemActionId =
|
||||||
|
result.data.order_preview.items[0].actions[0].id
|
||||||
|
|
||||||
|
result = await api.post(
|
||||||
|
`/admin/returns/${returnId}/request-items/${updateReturnItemActionId}`,
|
||||||
|
{
|
||||||
|
quantity: 2,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
result = await api.post(
|
||||||
|
`/admin/returns/${returnId}/request`,
|
||||||
|
{},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
// Simple lifecyle:
|
// Simple lifecyle:
|
||||||
// 1. Initiate return
|
// 1. Initiate return
|
||||||
// 2. Request to return items
|
// 2. Request to return items
|
||||||
@@ -195,8 +325,6 @@ medusaIntegrationTestRunner({
|
|||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
order_id: order.id,
|
order_id: order.id,
|
||||||
display_id: 1,
|
|
||||||
order_version: 2,
|
|
||||||
status: "requested",
|
status: "requested",
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export function prepareLineItemData(data: Input) {
|
|||||||
product_title: variant.product.title,
|
product_title: variant.product.title,
|
||||||
product_description: variant.product.description,
|
product_description: variant.product.description,
|
||||||
product_subtitle: variant.product.subtitle,
|
product_subtitle: variant.product.subtitle,
|
||||||
product_type: variant.product.type?.[0].value ?? null,
|
product_type: variant.product.type?.[0]?.value ?? null,
|
||||||
product_collection: variant.product.collection?.[0]?.value ?? null,
|
product_collection: variant.product.collection?.[0]?.value ?? null,
|
||||||
product_handle: variant.product.handle,
|
product_handle: variant.product.handle,
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
|
CreateOrderReturnItemDTO,
|
||||||
IOrderModuleService,
|
IOrderModuleService,
|
||||||
OrderChangeActionDTO,
|
OrderChangeActionDTO,
|
||||||
UpdateReturnDTO,
|
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||||
@@ -21,33 +21,24 @@ export const createReturnItemsStep = createStep(
|
|||||||
const returnItems = input.changes.map((item) => {
|
const returnItems = input.changes.map((item) => {
|
||||||
return {
|
return {
|
||||||
return_id: input.returnId,
|
return_id: input.returnId,
|
||||||
item_id: item.details?.reference_id,
|
item_id: item.details?.reference_id! as string,
|
||||||
reason_id: item.details?.reason_id,
|
reason_id: item.details?.reason_id,
|
||||||
quantity: item.details?.quantity as number,
|
quantity: item.details?.quantity as number,
|
||||||
note: item.internal_note,
|
note: item.internal_note,
|
||||||
metadata: (item.details?.metadata as Record<string, unknown>) ?? {},
|
metadata: (item.details?.metadata as Record<string, unknown>) ?? {},
|
||||||
}
|
} as CreateOrderReturnItemDTO
|
||||||
})
|
})
|
||||||
|
const createdReturnItems = await orderModuleService.createReturnItems(
|
||||||
const [prevReturn] = await orderModuleService.listReturns(
|
returnItems
|
||||||
{ id: input.returnId },
|
|
||||||
{
|
|
||||||
select: ["id"],
|
|
||||||
relations: ["items"],
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const createdReturnItems = await orderModuleService.updateReturns([
|
return new StepResponse(
|
||||||
{
|
createdReturnItems,
|
||||||
selector: { id: input.returnId },
|
createdReturnItems.map((i) => i.id)
|
||||||
data: { items: returnItems as UpdateReturnDTO["items"] },
|
)
|
||||||
},
|
},
|
||||||
])
|
async (ids, { container }) => {
|
||||||
|
if (!ids) {
|
||||||
return new StepResponse(createdReturnItems, prevReturn)
|
|
||||||
},
|
|
||||||
async (prevData, { container }) => {
|
|
||||||
if (!prevData) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,9 +46,6 @@ export const createReturnItemsStep = createStep(
|
|||||||
ModuleRegistrationName.ORDER
|
ModuleRegistrationName.ORDER
|
||||||
)
|
)
|
||||||
|
|
||||||
await orderModuleService.updateReturns(
|
await orderModuleService.deleteReturnItems(ids)
|
||||||
{ id: prevData.id },
|
|
||||||
{ items: prevData.items }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -222,7 +222,7 @@ export const createOrderFulfillmentWorkflow = createWorkflow(
|
|||||||
})
|
})
|
||||||
|
|
||||||
const shippingMethod = transform(order, (data) => {
|
const shippingMethod = transform(order, (data) => {
|
||||||
return { data: data.shipping_methods?.[0].data }
|
return { data: data.shipping_methods?.[0]?.data }
|
||||||
})
|
})
|
||||||
|
|
||||||
const shippingOptionId = transform(order, (data) => {
|
const shippingOptionId = transform(order, (data) => {
|
||||||
|
|||||||
@@ -1139,6 +1139,21 @@ export interface ReturnDTO extends Omit<OrderDTO, "status" | "version"> {
|
|||||||
order_id: string
|
order_id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OrderReturnItemDTO {
|
||||||
|
id: string
|
||||||
|
return_id: string
|
||||||
|
order_id: string
|
||||||
|
item_id: string
|
||||||
|
reason_id?: string | null
|
||||||
|
quantity: number
|
||||||
|
raw_quantity: BigNumberRawValue
|
||||||
|
received_quantity?: number
|
||||||
|
raw_received_quantity?: BigNumberRawValue
|
||||||
|
metadata?: Record<string, unknown> | null
|
||||||
|
created_at?: Date | string
|
||||||
|
updated_at?: Date | string
|
||||||
|
}
|
||||||
|
|
||||||
export interface OrderClaimDTO
|
export interface OrderClaimDTO
|
||||||
extends Omit<OrderDTO, "status" | "version" | "items"> {
|
extends Omit<OrderDTO, "status" | "version" | "items"> {
|
||||||
claim_items: any[]
|
claim_items: any[]
|
||||||
|
|||||||
@@ -470,6 +470,15 @@ export interface UpdateOrderExchangeDTO {
|
|||||||
metadata?: Record<string, unknown> | null
|
metadata?: Record<string, unknown> | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreateOrderReturnItemDTO {
|
||||||
|
return_id: string
|
||||||
|
item_id: string
|
||||||
|
quantity?: BigNumberInput
|
||||||
|
reason_id?: string
|
||||||
|
note?: string
|
||||||
|
metadata?: Record<string, unknown> | null
|
||||||
|
}
|
||||||
|
|
||||||
export interface UpdateOrderReturnWithSelectorDTO {
|
export interface UpdateOrderReturnWithSelectorDTO {
|
||||||
selector: Partial<ReturnDTO>
|
selector: Partial<ReturnDTO>
|
||||||
data: Partial<UpdateReturnDTO>
|
data: Partial<UpdateReturnDTO>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import {
|
|||||||
OrderLineItemAdjustmentDTO,
|
OrderLineItemAdjustmentDTO,
|
||||||
OrderLineItemDTO,
|
OrderLineItemDTO,
|
||||||
OrderLineItemTaxLineDTO,
|
OrderLineItemTaxLineDTO,
|
||||||
|
OrderReturnItemDTO,
|
||||||
OrderReturnReasonDTO,
|
OrderReturnReasonDTO,
|
||||||
OrderShippingMethodAdjustmentDTO,
|
OrderShippingMethodAdjustmentDTO,
|
||||||
OrderShippingMethodDTO,
|
OrderShippingMethodDTO,
|
||||||
@@ -52,6 +53,7 @@ import {
|
|||||||
CreateOrderLineItemDTO,
|
CreateOrderLineItemDTO,
|
||||||
CreateOrderLineItemTaxLineDTO,
|
CreateOrderLineItemTaxLineDTO,
|
||||||
CreateOrderReturnDTO,
|
CreateOrderReturnDTO,
|
||||||
|
CreateOrderReturnItemDTO,
|
||||||
CreateOrderReturnReasonDTO,
|
CreateOrderReturnReasonDTO,
|
||||||
CreateOrderShippingMethodAdjustmentDTO,
|
CreateOrderShippingMethodAdjustmentDTO,
|
||||||
CreateOrderShippingMethodDTO,
|
CreateOrderShippingMethodDTO,
|
||||||
@@ -1891,6 +1893,16 @@ export interface IOrderModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<Record<string, string[]> | void>
|
): Promise<Record<string, string[]> | void>
|
||||||
|
|
||||||
|
createReturnItems(
|
||||||
|
data: CreateOrderReturnItemDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<OrderReturnItemDTO>
|
||||||
|
|
||||||
|
createReturnItems(
|
||||||
|
data: CreateOrderReturnItemDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<OrderReturnItemDTO[]>
|
||||||
|
|
||||||
createReturns(
|
createReturns(
|
||||||
data: CreateOrderReturnDTO,
|
data: CreateOrderReturnDTO,
|
||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
@@ -1916,6 +1928,8 @@ export interface IOrderModuleService extends IModuleService {
|
|||||||
|
|
||||||
deleteReturns(ids: string[], sharedContext?: Context): Promise<void>
|
deleteReturns(ids: string[], sharedContext?: Context): Promise<void>
|
||||||
|
|
||||||
|
deleteReturnItems(ids: string[], sharedContext?: Context): Promise<void>
|
||||||
|
|
||||||
softDeleteReturns<TReturnableLinkableKeys extends string = string>(
|
softDeleteReturns<TReturnableLinkableKeys extends string = string>(
|
||||||
ids: string[],
|
ids: string[],
|
||||||
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||||
|
|||||||
@@ -81,12 +81,12 @@ export default class ClaimItemImage {
|
|||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
onCreate() {
|
onCreate() {
|
||||||
this.id = generateEntityId(this.id, "climg")
|
this.id = generateEntityId(this.id, "climg")
|
||||||
this.claim_item_id = this.item?.id
|
this.claim_item_id ??= this.item?.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnInit()
|
@OnInit()
|
||||||
onInit() {
|
onInit() {
|
||||||
this.id = generateEntityId(this.id, "climg")
|
this.id = generateEntityId(this.id, "climg")
|
||||||
this.claim_item_id = this.item?.id
|
this.claim_item_id ??= this.item?.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,6 +129,6 @@ export default class OrderClaimItem {
|
|||||||
@OnInit()
|
@OnInit()
|
||||||
onInit() {
|
onInit() {
|
||||||
this.id = generateEntityId(this.id, "claitem")
|
this.id = generateEntityId(this.id, "claitem")
|
||||||
this.claim_id = this.claim?.id
|
this.claim_id ??= this.claim?.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,12 +105,12 @@ export default class OrderExchangeItem {
|
|||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
onCreate() {
|
onCreate() {
|
||||||
this.id = generateEntityId(this.id, "oexcitem")
|
this.id = generateEntityId(this.id, "oexcitem")
|
||||||
this.exchange_id = this.exchange?.id
|
this.exchange_id ??= this.exchange?.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnInit()
|
@OnInit()
|
||||||
onInit() {
|
onInit() {
|
||||||
this.id = generateEntityId(this.id, "oexcitem")
|
this.id = generateEntityId(this.id, "oexcitem")
|
||||||
this.exchange_id = this.exchange?.id
|
this.exchange_id ??= this.exchange?.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,12 +132,12 @@ export default class ReturnItem {
|
|||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
onCreate() {
|
onCreate() {
|
||||||
this.id = generateEntityId(this.id, "retitem")
|
this.id = generateEntityId(this.id, "retitem")
|
||||||
this.return_id = this.return?.id
|
this.return_id ??= this.return?.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnInit()
|
@OnInit()
|
||||||
onInit() {
|
onInit() {
|
||||||
this.id = generateEntityId(this.id, "retitem")
|
this.id = generateEntityId(this.id, "retitem")
|
||||||
this.return_id = this.return?.id
|
this.return_id ??= this.return?.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user