diff --git a/.changeset/unlucky-pumpkins-nail.md b/.changeset/unlucky-pumpkins-nail.md new file mode 100644 index 0000000000..632a2acdd3 --- /dev/null +++ b/.changeset/unlucky-pumpkins-nail.md @@ -0,0 +1,8 @@ +--- +"@medusajs/dashboard": patch +"@medusajs/core-flows": patch +"@medusajs/types": patch +"@medusajs/medusa": patch +--- + +fix(dashboard,core-flows,types,medusa): Allow editing Order metadata diff --git a/packages/admin/dashboard/src/providers/router-provider/route-map.tsx b/packages/admin/dashboard/src/providers/router-provider/route-map.tsx index fbcf8fab74..5d8fc1f958 100644 --- a/packages/admin/dashboard/src/providers/router-provider/route-map.tsx +++ b/packages/admin/dashboard/src/providers/router-provider/route-map.tsx @@ -355,6 +355,10 @@ export const RouteMap: RouteObject[] = [ lazy: () => import("../../routes/orders/order-edit-billing-address"), }, + { + path: "metadata/edit", + lazy: () => import("../../routes/orders/order-metadata"), + }, ], }, ], diff --git a/packages/admin/dashboard/src/routes/orders/order-detail/constants.ts b/packages/admin/dashboard/src/routes/orders/order-detail/constants.ts index ae13fbb92f..446ff7e218 100644 --- a/packages/admin/dashboard/src/routes/orders/order-detail/constants.ts +++ b/packages/admin/dashboard/src/routes/orders/order-detail/constants.ts @@ -6,6 +6,7 @@ const DEFAULT_PROPERTIES = [ "email", "display_id", "currency_code", + "metadata", // --- TOTALS --- "total", "item_total", diff --git a/packages/admin/dashboard/src/routes/orders/order-detail/order-detail.tsx b/packages/admin/dashboard/src/routes/orders/order-detail/order-detail.tsx index 2e1a5c4916..de80b0be3b 100644 --- a/packages/admin/dashboard/src/routes/orders/order-detail/order-detail.tsx +++ b/packages/admin/dashboard/src/routes/orders/order-detail/order-detail.tsx @@ -72,6 +72,7 @@ export const OrderDetail = () => { }} data={order} showJSON + showMetadata hasOutlet > diff --git a/packages/admin/dashboard/src/routes/orders/order-metadata/index.ts b/packages/admin/dashboard/src/routes/orders/order-metadata/index.ts new file mode 100644 index 0000000000..74be4d2982 --- /dev/null +++ b/packages/admin/dashboard/src/routes/orders/order-metadata/index.ts @@ -0,0 +1 @@ +export { OrderMetadata as Component } from "./order-metadata" diff --git a/packages/admin/dashboard/src/routes/orders/order-metadata/order-metadata.tsx b/packages/admin/dashboard/src/routes/orders/order-metadata/order-metadata.tsx new file mode 100644 index 0000000000..ac21edca42 --- /dev/null +++ b/packages/admin/dashboard/src/routes/orders/order-metadata/order-metadata.tsx @@ -0,0 +1,26 @@ +import { useParams } from "react-router-dom" +import { MetadataForm } from "../../../components/forms/metadata-form/metadata-form" +import { useOrder, useUpdateOrder } from "../../../hooks/api" + +export const OrderMetadata = () => { + const { id } = useParams() + + const { order, isPending, isError, error } = useOrder(id!, { + fields: "id,metadata", + }) + + const { mutateAsync, isPending: isMutating } = useUpdateOrder(order?.id!) + + if (isError) { + throw error + } + + return ( + + ) +} diff --git a/packages/core/core-flows/src/order/workflows/update-order.ts b/packages/core/core-flows/src/order/workflows/update-order.ts index fc036cdf0d..1bfe2afd09 100644 --- a/packages/core/core-flows/src/order/workflows/update-order.ts +++ b/packages/core/core-flows/src/order/workflows/update-order.ts @@ -1,4 +1,9 @@ import { OrderDTO, OrderWorkflow } from "@medusajs/framework/types" +import { + MedusaError, + OrderWorkflowEvents, + validateEmail, +} from "@medusajs/framework/utils" import { WorkflowData, WorkflowResponse, @@ -11,19 +16,14 @@ import { RegisterOrderChangeDTO, UpdateOrderDTO, } from "@medusajs/types" -import { - MedusaError, - OrderWorkflowEvents, - validateEmail, -} from "@medusajs/framework/utils" -import { throwIfOrderIsCancelled } from "../utils/order-validation" +import { emitEventStep, useQueryGraphStep } from "../../common" import { previewOrderChangeStep, registerOrderChangesStep, updateOrdersStep, } from "../steps" -import { emitEventStep, useQueryGraphStep } from "../../common" +import { throwIfOrderIsCancelled } from "../utils/order-validation" /** * The data to validate the order update. @@ -42,14 +42,14 @@ export type UpdateOrderValidationStepInput = { /** * This step validates that an order can be updated with provided input. If the order is cancelled, * the email is invalid, or the country code is being changed in the shipping or billing addresses, the step will throw an error. - * + * * :::note - * + * * You can retrieve an order's details using [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query), * or [useQueryGraphStep](https://docs.medusajs.com/resources/references/medusa-workflows/steps/useQueryGraphStep). - * + * * ::: - * + * * @example * const data = updateOrderValidationStep({ * order: { @@ -64,10 +64,7 @@ export type UpdateOrderValidationStepInput = { */ export const updateOrderValidationStep = createStep( "update-order-validation", - async function ({ - order, - input, - }: UpdateOrderValidationStepInput) { + async function ({ order, input }: UpdateOrderValidationStepInput) { throwIfOrderIsCancelled({ order }) if ( @@ -100,12 +97,12 @@ export const updateOrderValidationStep = createStep( export const updateOrderWorkflowId = "update-order-workflow" /** - * This workflow updates an order's general details, such as its email or addresses. It's used by the + * This workflow updates an order's general details, such as its email or addresses. It's used by the * [Update Order Admin API Route](https://docs.medusajs.com/api/admin#orders_postordersid). - * + * * You can use this workflow within your customizations or your own custom workflows, allowing you to update an * order's details in your custom flows. - * + * * @example * const { result } = await updateOrderWorkflow(container) * .run({ @@ -115,9 +112,9 @@ export const updateOrderWorkflowId = "update-order-workflow" * email: "example@gmail.com", * } * }) - * + * * @summary - * + * * Update an order's details. */ export const updateOrderWorkflow = createWorkflow( @@ -133,6 +130,7 @@ export const updateOrderWorkflow = createWorkflow( "email", "shipping_address.*", "billing_address.*", + "metadata", ], filters: { id: input.id }, options: { throwIfKeyNotFound: true }, @@ -223,6 +221,20 @@ export const updateOrderWorkflow = createWorkflow( }) } + if (input.metadata !== undefined) { + changes.push({ + change_type: "update_order" as const, + order_id: input.id, + created_by: input.user_id, + confirmed_by: input.user_id, + details: { + type: "metadata", + old: order.metadata, + new: input.metadata, + }, + }) + } + return changes } ) diff --git a/packages/core/types/src/http/order/admin/payload.ts b/packages/core/types/src/http/order/admin/payload.ts index 5c93ba55ec..98e72cc46d 100644 --- a/packages/core/types/src/http/order/admin/payload.ts +++ b/packages/core/types/src/http/order/admin/payload.ts @@ -11,6 +11,10 @@ export interface AdminUpdateOrder { * The order's billing address. */ billing_address?: OrderAddress + /** + * The order's metadata. + */ + metadata?: Record | null } export interface AdminCreateOrderFulfillment { diff --git a/packages/core/types/src/workflow/order/update-order.ts b/packages/core/types/src/workflow/order/update-order.ts index bcc0f3ea42..f2712e7613 100644 --- a/packages/core/types/src/workflow/order/update-order.ts +++ b/packages/core/types/src/workflow/order/update-order.ts @@ -26,6 +26,10 @@ export type UpdateOrderWorkflowInput = { * The new email of the order. */ email?: string + /** + * The new metadata of the order. + */ + metadata?: Record | null } export type UpdateOrderShippingAddressWorkflowInput = { diff --git a/packages/medusa/src/api/admin/orders/[id]/route.ts b/packages/medusa/src/api/admin/orders/[id]/route.ts index 0e48284dfb..59f1b13280 100644 --- a/packages/medusa/src/api/admin/orders/[id]/route.ts +++ b/packages/medusa/src/api/admin/orders/[id]/route.ts @@ -7,11 +7,11 @@ import { MedusaResponse, } from "@medusajs/framework/http" import { AdminOrder, HttpTypes } from "@medusajs/framework/types" +import { ContainerRegistrationKeys } from "@medusajs/framework/utils" import { AdminGetOrdersOrderParamsType, AdminUpdateOrderType, } from "../validators" -import { ContainerRegistrationKeys } from "@medusajs/framework/utils" export const GET = async ( req: AuthenticatedMedusaRequest, diff --git a/packages/medusa/src/api/admin/orders/validators.ts b/packages/medusa/src/api/admin/orders/validators.ts index 49a260d896..9730081671 100644 --- a/packages/medusa/src/api/admin/orders/validators.ts +++ b/packages/medusa/src/api/admin/orders/validators.ts @@ -1,11 +1,11 @@ import { z } from "zod" +import { AddressPayload } from "../../utils/common-validators" import { createFindParams, createOperatorMap, createSelectParams, WithAdditionalData, } from "../../utils/validators" -import { AddressPayload } from "../../utils/common-validators" export const AdminGetOrdersOrderParams = createSelectParams().merge( z.object({ @@ -144,4 +144,5 @@ export const AdminUpdateOrder = z.object({ email: z.string().optional(), shipping_address: AddressPayload.optional(), billing_address: AddressPayload.optional(), + metadata: z.record(z.unknown()).nullish(), })