feat(core-flow): order edit endpoints (#8596)

* The relevant part of this PR is only at folder `packages/medusa/src/api/admin/order-edits/`
All the other changes are Types

Missing: 
* `/store` endpoints to confirm/decline the order change
* http tests of the full flow
This commit is contained in:
Carlos R. L. Rodrigues
2024-08-15 16:59:36 +00:00
committed by GitHub
parent b23ddcdde8
commit c92aa3e397
63 changed files with 600 additions and 92 deletions
@@ -2,6 +2,7 @@ import {
removeItemExchangeActionWorkflow,
updateExchangeAddItemWorkflow,
} from "@medusajs/core-flows"
import { HttpTypes } from "@medusajs/types"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
@@ -10,11 +11,10 @@ import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../../types/routing"
import { AdminPostExhangesItemsActionReqSchemaType } from "../../../../validators"
import { HttpTypes } from "@medusajs/types"
import { AdminPostExchangesItemsActionReqSchemaType } from "../../../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostExhangesItemsActionReqSchemaType>,
req: AuthenticatedMedusaRequest<AdminPostExchangesItemsActionReqSchemaType>,
res: MedusaResponse<HttpTypes.AdminExchangePreviewResponse>
) => {
const { id, action_id } = req.params
@@ -7,11 +7,11 @@ import {
AdminGetOrdersParams,
AdminPostCancelExchangeReqSchema,
AdminPostExchangesAddItemsReqSchema,
AdminPostExchangesItemsActionReqSchema,
AdminPostExchangesRequestItemsReturnActionReqSchema,
AdminPostExchangesReturnRequestItemsReqSchema,
AdminPostExchangesShippingActionReqSchema,
AdminPostExchangesShippingReqSchema,
AdminPostExhangesItemsActionReqSchema,
AdminPostOrderExchangesReqSchema,
} from "./validators"
@@ -129,7 +129,7 @@ export const adminExchangeRoutesMiddlewares: MiddlewareRoute[] = [
method: ["POST"],
matcher: "/admin/exchanges/:id/outbound/items/:action_id",
middlewares: [
validateAndTransformBody(AdminPostExhangesItemsActionReqSchema),
validateAndTransformBody(AdminPostExchangesItemsActionReqSchema),
validateAndTransformQuery(
AdminGetOrdersOrderParams,
QueryConfig.retrieveTransformQueryConfig
@@ -160,11 +160,11 @@ export type AdminPostExchangesConfirmRequestReqSchemaType = z.infer<
typeof AdminPostExchangesConfirmRequestReqSchema
>
export const AdminPostExhangesItemsActionReqSchema = z.object({
export const AdminPostExchangesItemsActionReqSchema = z.object({
quantity: z.number().optional(),
internal_note: z.string().nullish().optional(),
})
export type AdminPostExhangesItemsActionReqSchemaType = z.infer<
typeof AdminPostExhangesItemsActionReqSchema
export type AdminPostExchangesItemsActionReqSchemaType = z.infer<
typeof AdminPostExchangesItemsActionReqSchema
>
@@ -0,0 +1,21 @@
import { confirmOrderEditRequestWorkflow } from "@medusajs/core-flows"
import { HttpTypes } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
export const POST = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse<HttpTypes.AdminOrderEditPreviewResponse>
) => {
const { id } = req.params
const { result } = await confirmOrderEditRequestWorkflow(req.scope).run({
input: { order_id: id },
})
res.json({
order_preview: result,
})
}
@@ -0,0 +1,49 @@
import {
removeItemOrderEditActionWorkflow,
updateOrderEditAddItemWorkflow,
} from "@medusajs/core-flows"
import { HttpTypes } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../types/routing"
import { AdminPostOrderEditsItemsActionReqSchemaType } from "../../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostOrderEditsItemsActionReqSchemaType>,
res: MedusaResponse<HttpTypes.AdminOrderEditPreviewResponse>
) => {
const { id, action_id } = req.params
const { result } = await updateOrderEditAddItemWorkflow(req.scope).run({
input: {
data: { ...req.validatedBody },
order_id: id,
action_id,
},
})
res.json({
order_preview: result,
})
}
export const DELETE = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse<HttpTypes.AdminOrderEditPreviewResponse>
) => {
const { id, action_id } = req.params
const { result: orderPreview } = await removeItemOrderEditActionWorkflow(
req.scope
).run({
input: {
order_id: id,
action_id,
},
})
res.json({
order_preview: orderPreview,
})
}
@@ -0,0 +1,23 @@
import { orderEditAddNewItemWorkflow } from "@medusajs/core-flows"
import { HttpTypes } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
import { AdminPostOrderEditsAddItemsReqSchemaType } from "../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostOrderEditsAddItemsReqSchemaType>,
res: MedusaResponse<HttpTypes.AdminOrderEditPreviewResponse>
) => {
const { id } = req.params
const { result } = await orderEditAddNewItemWorkflow(req.scope).run({
input: { ...req.validatedBody, order_id: id },
})
res.json({
order_preview: result,
})
}
@@ -0,0 +1,25 @@
import { cancelBeginOrderEditWorkflow } from "@medusajs/core-flows"
import { DeleteResponse } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../types/routing"
export const DELETE = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse<DeleteResponse<"order-edit">>
) => {
const { id } = req.params
await cancelBeginOrderEditWorkflow(req.scope).run({
input: {
order_id: id,
},
})
res.status(200).json({
id,
object: "order-edit",
deleted: true,
})
}
@@ -0,0 +1,51 @@
import {
removeOrderEditShippingMethodWorkflow,
updateOrderEditShippingMethodWorkflow,
} from "@medusajs/core-flows"
import { HttpTypes } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../types/routing"
import { AdminPostOrderEditsShippingActionReqSchemaType } from "../../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostOrderEditsShippingActionReqSchemaType>,
res: MedusaResponse<HttpTypes.AdminOrderEditPreviewResponse>
) => {
const { id, action_id } = req.params
const { result } = await updateOrderEditShippingMethodWorkflow(req.scope).run(
{
input: {
data: { ...req.validatedBody },
order_id: id,
action_id,
},
}
)
res.json({
order_preview: result,
})
}
export const DELETE = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse<HttpTypes.AdminOrderEditPreviewResponse>
) => {
const { id, action_id } = req.params
const { result: orderPreview } = await removeOrderEditShippingMethodWorkflow(
req.scope
).run({
input: {
order_id: id,
action_id,
},
})
res.json({
order_preview: orderPreview,
})
}
@@ -0,0 +1,24 @@
import { createOrderEditShippingMethodWorkflow } from "@medusajs/core-flows"
import { HttpTypes } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
import { AdminPostOrderEditsShippingReqSchemaType } from "../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostOrderEditsShippingReqSchemaType>,
res: MedusaResponse<HttpTypes.AdminOrderEditPreviewResponse>
) => {
const { id } = req.params
const { result } = await createOrderEditShippingMethodWorkflow(req.scope).run(
{
input: { ...req.validatedBody, order_id: id },
}
)
res.json({
order_preview: result,
})
}
@@ -0,0 +1,71 @@
import { MiddlewareRoute } from "@medusajs/framework"
import { validateAndTransformBody } from "../../utils/validate-body"
import {
AdminPostOrderEditsAddItemsReqSchema,
AdminPostOrderEditsItemsActionReqSchema,
AdminPostOrderEditsReqSchema,
AdminPostOrderEditsShippingActionReqSchema,
AdminPostOrderEditsShippingReqSchema,
} from "./validators"
export const adminOrderEditRoutesMiddlewares: MiddlewareRoute[] = [
{
method: ["GET"],
matcher: "/admin/order-edits/:id",
middlewares: [],
},
{
method: ["POST"],
matcher: "/admin/order-edits",
middlewares: [validateAndTransformBody(AdminPostOrderEditsReqSchema)],
},
{
method: ["POST"],
matcher: "/admin/order-edits/:id/items",
middlewares: [
validateAndTransformBody(AdminPostOrderEditsAddItemsReqSchema),
],
},
{
method: ["POST"],
matcher: "/admin/order-edits/:id/items/:action_id",
middlewares: [
validateAndTransformBody(AdminPostOrderEditsItemsActionReqSchema),
],
},
{
method: ["DELETE"],
matcher: "/admin/order-edits/:id/items/:action_id",
middlewares: [],
},
{
method: ["POST"],
matcher: "/admin/order-edits/:id/shipping-method",
middlewares: [
validateAndTransformBody(AdminPostOrderEditsShippingReqSchema),
],
},
{
method: ["POST"],
matcher: "/admin/order-edits/:id/shipping-method/:action_id",
middlewares: [
validateAndTransformBody(AdminPostOrderEditsShippingActionReqSchema),
],
},
{
method: ["DELETE"],
matcher: "/admin/order-edits/:id/shipping-method/:action_id",
middlewares: [],
},
{
method: ["POST"],
matcher: "/admin/order-edits/:id/confirm",
middlewares: [],
},
{
method: ["DELETE"],
matcher: "/admin/order-edits/:id",
middlewares: [],
},
]
@@ -0,0 +1,24 @@
export const defaultAdminOrderEditFields = [
"id",
"order_id",
"display_id",
"order_version",
"created_at",
"updated_at",
"canceled_at",
]
export const defaultAdminDetailsOrderEditFields = [
...defaultAdminOrderEditFields,
]
export const retrieveTransformQueryConfig = {
defaultFields: defaultAdminDetailsOrderEditFields,
isList: false,
}
export const listTransformQueryConfig = {
defaults: defaultAdminOrderEditFields,
defaultLimit: 20,
isList: true,
}
@@ -0,0 +1,41 @@
import { beginOrderEditOrderWorkflow } from "@medusajs/core-flows"
import { HttpTypes } from "@medusajs/types"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../types/routing"
import { AdminPostOrderEditsReqSchemaType } from "./validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostOrderEditsReqSchemaType>,
res: MedusaResponse<HttpTypes.AdminOrderResponse>
) => {
const input = req.validatedBody as AdminPostOrderEditsReqSchemaType
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const workflow = beginOrderEditOrderWorkflow(req.scope)
const { result } = await workflow.run({
input,
})
const queryObject = remoteQueryObjectFromString({
entryPoint: "order",
variables: {
id: result.order_id,
filters: {
...req.filterableFields,
},
},
fields: req.remoteQueryConfig.fields,
})
const [order] = await remoteQuery(queryObject)
res.json({
order,
})
}
@@ -0,0 +1,58 @@
import { z } from "zod"
export const AdminPostOrderEditsReqSchema = z.object({
order_id: z.string(),
description: z.string().optional(),
internal_note: z.string().optional(),
metadata: z.record(z.unknown()).nullish(),
})
export type AdminPostOrderEditsReqSchemaType = z.infer<
typeof AdminPostOrderEditsReqSchema
>
export const AdminPostOrderEditsShippingReqSchema = z.object({
shipping_option_id: z.string(),
custom_price: z.number().optional(),
description: z.string().optional(),
internal_note: z.string().optional(),
metadata: z.record(z.unknown()).optional(),
})
export type AdminPostOrderEditsShippingReqSchemaType = z.infer<
typeof AdminPostOrderEditsShippingReqSchema
>
export const AdminPostOrderEditsShippingActionReqSchema = z.object({
custom_price: z.number().optional(),
internal_note: z.string().nullish().optional(),
metadata: z.record(z.unknown()).nullish().optional(),
})
export type AdminPostOrderEditsShippingActionReqSchemaType = z.infer<
typeof AdminPostOrderEditsShippingActionReqSchema
>
export const AdminPostOrderEditsAddItemsReqSchema = z.object({
items: z.array(
z.object({
variant_id: z.string(),
quantity: z.number(),
unit_price: z.number().optional(),
internal_note: z.string().optional(),
allow_backorder: z.boolean().optional(),
metadata: z.record(z.unknown()).optional(),
})
),
})
export type AdminPostOrderEditsAddItemsReqSchemaType = z.infer<
typeof AdminPostOrderEditsAddItemsReqSchema
>
export const AdminPostOrderEditsItemsActionReqSchema = z.object({
quantity: z.number().optional(),
internal_note: z.string().nullish().optional(),
})
export type AdminPostOrderEditsItemsActionReqSchemaType = z.infer<
typeof AdminPostOrderEditsItemsActionReqSchema
>
+2
View File
@@ -14,6 +14,7 @@ import { adminFulfillmentsRoutesMiddlewares } from "./admin/fulfillments/middlew
import { adminInventoryRoutesMiddlewares } from "./admin/inventory-items/middlewares"
import { adminInviteRoutesMiddlewares } from "./admin/invites/middlewares"
import { adminNotificationRoutesMiddlewares } from "./admin/notifications/middlewares"
import { adminOrderEditRoutesMiddlewares } from "./admin/order-edits/middlewares"
import { adminOrderRoutesMiddlewares } from "./admin/orders/middlewares"
import { adminPaymentRoutesMiddlewares } from "./admin/payments/middlewares"
import { adminPriceListsRoutesMiddlewares } from "./admin/price-lists/middlewares"
@@ -112,4 +113,5 @@ export default defineMiddlewares([
...adminRefundReasonsRoutesMiddlewares,
...adminExchangeRoutesMiddlewares,
...adminProductVariantRoutesMiddlewares,
...adminOrderEditRoutesMiddlewares,
])