Skip to content

Commit feabe0e

Browse files
authored
feat: update return request (#8302)
1 parent a4eab3f commit feabe0e

File tree

13 files changed

+216
-3
lines changed

13 files changed

+216
-3
lines changed

integration-tests/http/__tests__/returns/returns.spec.ts

+19
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,25 @@ medusaIntegrationTestRunner({
420420
})
421421
)
422422

423+
result = await api.post(
424+
`/admin/returns/${returnId}`,
425+
{
426+
location_id: location.id,
427+
metadata: { hello: "world" },
428+
no_notification: true,
429+
},
430+
adminHeaders
431+
)
432+
433+
expect(result.data.return).toEqual(
434+
expect.objectContaining({
435+
id: returnId,
436+
location_id: location.id,
437+
metadata: { hello: "world" },
438+
no_notification: true,
439+
})
440+
)
441+
423442
const item = order.items[0]
424443

425444
result = await api.post(

packages/admin-next/dashboard/src/hooks/api/returns.tsx

+23
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,29 @@ export const useRemoveReturnItem = (
151151
})
152152
}
153153

154+
export const useUpdateReturn = (
155+
id: string,
156+
orderId: string,
157+
options?: UseMutationOptions<
158+
HttpTypes.AdminReturnResponse,
159+
Error,
160+
HttpTypes.AdminUpdateReturnRequest
161+
>
162+
) => {
163+
return useMutation({
164+
mutationFn: (payload: HttpTypes.AdminUpdateReturnRequest) => {
165+
return sdk.admin.return.updateRequest(id, payload)
166+
},
167+
onSuccess: (data: any, variables: any, context: any) => {
168+
queryClient.invalidateQueries({
169+
queryKey: ordersQueryKeys.preview(orderId),
170+
})
171+
options?.onSuccess?.(data, variables, context)
172+
},
173+
...options,
174+
})
175+
}
176+
154177
export const useAddReturnShipping = (
155178
id: string,
156179
orderId: string,

packages/admin-next/dashboard/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
useConfirmReturnRequest,
3838
useDeleteReturnShipping,
3939
useRemoveReturnItem,
40+
useUpdateReturn,
4041
useUpdateReturnItem,
4142
useUpdateReturnShipping,
4243
} from "../../../../../hooks/api/returns"
@@ -91,6 +92,8 @@ export const ReturnCreateForm = ({
9192

9293
const { mutateAsync: cancelReturnRequest, isPending: isCanceling } =
9394
useCancelReturnRequest(activeReturn.id, order.id)
95+
const { mutateAsync: updateReturnRequest, isPending: isUpdating } =
96+
useUpdateReturn(activeReturn.id, order.id)
9497

9598
const { mutateAsync: addReturnShipping, isPending: isAddingReturnShipping } =
9699
useAddReturnShipping(activeReturn.id, order.id)
@@ -122,7 +125,8 @@ export const ReturnCreateForm = ({
122125
isDeletingReturnShipping ||
123126
isAddingReturnItem ||
124127
isRemovingReturnItem ||
125-
isUpdatingReturnItem
128+
isUpdatingReturnItem ||
129+
isUpdating
126130

127131
/**
128132
* FORM
@@ -254,6 +258,10 @@ export const ReturnCreateForm = ({
254258
setIsOpen("items", false)
255259
}
256260

261+
const onLocationChange = async (selectedLocationId: string) => {
262+
await updateReturnRequest({ location_id: selectedLocationId })
263+
}
264+
257265
const onShippingOptionChange = async (selectedOptionId: string) => {
258266
const promises = preview.shipping_methods
259267
.map((s) => s.actions?.find((a) => a.action === "SHIPPING_ADD")?.id)
@@ -477,6 +485,7 @@ export const ReturnCreateForm = ({
477485
value={value}
478486
onChange={(v) => {
479487
onChange(v)
488+
onLocationChange(v)
480489
}}
481490
{...field}
482491
options={(stock_locations ?? []).map(

packages/core/core-flows/src/order/workflows/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ export * from "./return/remove-return-shipping-method"
4646
export * from "./return/request-item-return"
4747
export * from "./return/update-receive-item-return-request"
4848
export * from "./return/update-request-item-return"
49+
export * from "./return/update-return"
4950
export * from "./return/update-return-shipping-method"
5051
export * from "./update-order-change-actions"
5152
export * from "./update-tax-lines"
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { OrderChangeDTO, OrderWorkflow, ReturnDTO } from "@medusajs/types"
2+
import { OrderChangeStatus } from "@medusajs/utils"
3+
import {
4+
WorkflowData,
5+
createStep,
6+
createWorkflow,
7+
transform,
8+
} from "@medusajs/workflows-sdk"
9+
import { useRemoteQueryStep } from "../../../common"
10+
import { updateReturnsStep } from "../../steps"
11+
import { previewOrderChangeStep } from "../../steps/preview-order-change"
12+
import {
13+
throwIfIsCancelled,
14+
throwIfOrderChangeIsNotActive,
15+
} from "../../utils/order-validation"
16+
17+
const validationStep = createStep(
18+
"validate-update-return",
19+
async function ({
20+
orderChange,
21+
orderReturn,
22+
}: {
23+
orderReturn: ReturnDTO
24+
orderChange: OrderChangeDTO
25+
}) {
26+
throwIfIsCancelled(orderReturn, "Return")
27+
throwIfOrderChangeIsNotActive({ orderChange })
28+
}
29+
)
30+
31+
export const updateReturnWorkflowId = "update-return"
32+
export const updateReturnWorkflow = createWorkflow(
33+
updateReturnWorkflowId,
34+
function (
35+
input: WorkflowData<OrderWorkflow.UpdateReturnWorkflowInput>
36+
): WorkflowData {
37+
const orderReturn: ReturnDTO = useRemoteQueryStep({
38+
entry_point: "return",
39+
fields: ["id", "status", "order_id", "canceled_at"],
40+
variables: { id: input.return_id },
41+
list: false,
42+
throw_if_key_not_found: true,
43+
})
44+
45+
const orderChange: OrderChangeDTO = useRemoteQueryStep({
46+
entry_point: "order_change",
47+
fields: ["id", "status", "version", "actions.*"],
48+
variables: {
49+
filters: {
50+
order_id: orderReturn.order_id,
51+
return_id: orderReturn.id,
52+
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
53+
},
54+
},
55+
list: false,
56+
}).config({ name: "order-change-query" })
57+
58+
validationStep({ orderReturn, orderChange })
59+
60+
const updateData = transform({ input }, ({ input }) => {
61+
return {
62+
id: input.return_id,
63+
location_id: input.location_id,
64+
no_notification: input.no_notification,
65+
metadata: input.metadata,
66+
}
67+
})
68+
69+
updateReturnsStep([updateData])
70+
71+
return previewOrderChangeStep(orderReturn.order_id)
72+
}
73+
)

packages/core/js-sdk/src/admin/return.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FindParams, HttpTypes, SelectParams } from "@medusajs/types"
1+
import { HttpTypes, SelectParams } from "@medusajs/types"
22

33
import { Client } from "../client"
44
import { ClientHeaders } from "../types"
@@ -178,4 +178,21 @@ export class Return {
178178
}
179179
)
180180
}
181+
182+
async updateRequest(
183+
id: string,
184+
body: HttpTypes.AdminUpdateReturnRequest,
185+
query?: HttpTypes.SelectParams,
186+
headers?: ClientHeaders
187+
) {
188+
return await this.client.fetch<HttpTypes.AdminReturnResponse>(
189+
`/admin/returns/${id}`,
190+
{
191+
method: "POST",
192+
headers,
193+
body,
194+
query,
195+
}
196+
)
197+
}
181198
}

packages/core/types/src/http/return/admin.ts

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ export interface AdminConfirmReturnRequest {
7878
no_notification?: boolean
7979
}
8080

81+
export interface AdminUpdateReturnRequest {
82+
location_id?: string
83+
no_notification?: boolean
84+
metadata?: Record<string, unknown> | null
85+
}
86+
8187
export interface AdminReturnFilters extends FindParams {
8288
id?: string[] | string | OperatorMap<string | string[]>
8389
order_id?: string[] | string | OperatorMap<string | string[]>

packages/core/types/src/workflow/order/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ export * from "./items"
1313
export * from "./receive-return"
1414
export * from "./request-item-return"
1515
export * from "./shipping-method"
16+
export * from "./update-return"
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface UpdateReturnWorkflowInput {
2+
return_id: string
3+
location_id?: string
4+
no_notification?: boolean
5+
metadata?: Record<string, any> | null
6+
}

packages/medusa/src/api/admin/returns/[id]/route.ts

+33
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { updateReturnWorkflow } from "@medusajs/core-flows"
12
import {
23
ContainerRegistrationKeys,
34
remoteQueryObjectFromString,
@@ -6,6 +7,7 @@ import {
67
AuthenticatedMedusaRequest,
78
MedusaResponse,
89
} from "../../../../types/routing"
10+
import { AdminPostReturnsReturnReqSchemaType } from "../validators"
911

1012
export const GET = async (
1113
req: AuthenticatedMedusaRequest,
@@ -32,3 +34,34 @@ export const GET = async (
3234
return: orderReturn,
3335
})
3436
}
37+
38+
export const POST = async (
39+
req: AuthenticatedMedusaRequest<AdminPostReturnsReturnReqSchemaType>,
40+
res: MedusaResponse
41+
) => {
42+
const { id } = req.params
43+
44+
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
45+
46+
const { result } = await updateReturnWorkflow(req.scope).run({
47+
input: { return_id: id, ...req.validatedBody },
48+
})
49+
50+
const queryObject = remoteQueryObjectFromString({
51+
entryPoint: "return",
52+
variables: {
53+
id,
54+
filters: {
55+
...req.filterableFields,
56+
},
57+
},
58+
fields: req.remoteQueryConfig.fields,
59+
})
60+
61+
const [orderReturn] = await remoteQuery(queryObject)
62+
63+
res.json({
64+
order_preview: result,
65+
return: orderReturn,
66+
})
67+
}

packages/medusa/src/api/admin/returns/middlewares.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import * as QueryConfig from "./query-config"
55
import {
66
AdminGetOrdersOrderParams,
77
AdminGetOrdersParams,
8+
AdminPostCancelReturnReqSchema,
89
AdminPostReceiveReturnItemsReqSchema,
910
AdminPostReceiveReturnsReqSchema,
10-
AdminPostCancelReturnReqSchema,
1111
AdminPostReturnsConfirmRequestReqSchema,
1212
AdminPostReturnsReqSchema,
1313
AdminPostReturnsRequestItemsActionReqSchema,
1414
AdminPostReturnsRequestItemsReqSchema,
15+
AdminPostReturnsReturnReqSchema,
1516
AdminPostReturnsShippingActionReqSchema,
1617
AdminPostReturnsShippingReqSchema,
1718
} from "./validators"
@@ -37,6 +38,17 @@ export const adminReturnRoutesMiddlewares: MiddlewareRoute[] = [
3738
),
3839
],
3940
},
41+
{
42+
method: ["POST"],
43+
matcher: "/admin/returns/:id",
44+
middlewares: [
45+
validateAndTransformBody(AdminPostReturnsReturnReqSchema),
46+
validateAndTransformQuery(
47+
AdminGetOrdersOrderParams,
48+
QueryConfig.retrieveTransformQueryConfig
49+
),
50+
],
51+
},
4052
{
4153
method: ["POST"],
4254
matcher: "/admin/returns",

packages/medusa/src/api/admin/returns/query-config.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export const defaultAdminReturnFields = [
77
"location_id",
88
"order_version",
99
"status",
10+
"metadata",
11+
"no_notification",
1012
"refund_amount",
1113
"created_at",
1214
"updated_at",

packages/medusa/src/api/admin/returns/validators.ts

+9
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ export type AdminPostReturnsReqSchemaType = z.infer<
5050
typeof AdminPostReturnsReqSchema
5151
>
5252

53+
export const AdminPostReturnsReturnReqSchema = z.object({
54+
location_id: z.string().optional(),
55+
no_notification: z.boolean().optional(),
56+
metadata: z.record(z.unknown()).nullish(),
57+
})
58+
export type AdminPostReturnsReturnReqSchemaType = z.infer<
59+
typeof AdminPostReturnsReturnReqSchema
60+
>
61+
5362
export const AdminPostOrderExchangesReqSchema = z.object({
5463
order_id: z.string(),
5564
description: z.string().optional(),

0 commit comments

Comments
 (0)