feat(medusa): ordem items endpoint (#9646)
This commit is contained in:
committed by
GitHub
parent
0a37675f0e
commit
2a98be6b65
@@ -1,3 +1,4 @@
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import {
|
||||
ClaimReason,
|
||||
ClaimType,
|
||||
@@ -5,7 +6,6 @@ import {
|
||||
Modules,
|
||||
RuleOperator,
|
||||
} from "@medusajs/utils"
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import {
|
||||
adminHeaders,
|
||||
createAdminUser,
|
||||
@@ -1372,6 +1372,33 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
// additional items is one of the props that should be undefined
|
||||
expect(res.data.claim.additional_items).toBeUndefined()
|
||||
|
||||
const resLineItems = await api.get(
|
||||
`/admin/orders/${order.id}/line-items`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(resLineItems.data).toEqual(
|
||||
expect.objectContaining({
|
||||
order_items: [
|
||||
expect.objectContaining({
|
||||
order_id: order.id,
|
||||
item_id: item.id,
|
||||
version: 3,
|
||||
item: expect.objectContaining({
|
||||
title: "Custom Item 2",
|
||||
unit_price: 25,
|
||||
}),
|
||||
history: {
|
||||
version: {
|
||||
from: 1,
|
||||
to: 3,
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
@@ -22,6 +22,7 @@ export const getOrderDetailWorkflow = createWorkflow(
|
||||
input: WorkflowData<{
|
||||
fields: string[]
|
||||
order_id: string
|
||||
version?: number
|
||||
}>
|
||||
): WorkflowResponse<OrderDetailDTO> => {
|
||||
const fields = transform(input, ({ fields }) => {
|
||||
@@ -38,7 +39,10 @@ export const getOrderDetailWorkflow = createWorkflow(
|
||||
const order: OrderDTO = useRemoteQueryStep({
|
||||
entry_point: "orders",
|
||||
fields,
|
||||
variables: { id: input.order_id },
|
||||
variables: {
|
||||
id: input.order_id,
|
||||
version: input.version,
|
||||
},
|
||||
list: false,
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
@@ -116,7 +116,7 @@ export interface MedusaRequest<Body = unknown>
|
||||
*/
|
||||
remoteQueryConfig: {
|
||||
fields: string[]
|
||||
pagination: { order?: Record<string, string>; skip?: number; take?: number }
|
||||
pagination: { order?: Record<string, string>; skip: number; take?: number }
|
||||
}
|
||||
/**
|
||||
* An object containing the fields that are filterable e.g `{ id: Any<String> }`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import {
|
||||
isString,
|
||||
ContainerRegistrationKeys,
|
||||
isString,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { MedusaRequest } from "../types"
|
||||
@@ -11,7 +11,7 @@ export const refetchEntities = async (
|
||||
idOrFilter: string | object,
|
||||
scope: MedusaContainer,
|
||||
fields: string[],
|
||||
pagination: MedusaRequest["remoteQueryConfig"]["pagination"] = {}
|
||||
pagination?: MedusaRequest["remoteQueryConfig"]["pagination"]
|
||||
) => {
|
||||
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const filters = isString(idOrFilter) ? { id: idOrFilter } : idOrFilter
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { z } from "zod"
|
||||
import { omit } from "lodash"
|
||||
import { NextFunction } from "express"
|
||||
import { MedusaError, removeUndefinedProperties } from "@medusajs/utils"
|
||||
import { BaseEntity, QueryConfig, RequestQueryFields } from "@medusajs/types"
|
||||
import { MedusaError, removeUndefinedProperties } from "@medusajs/utils"
|
||||
import { NextFunction } from "express"
|
||||
import { omit } from "lodash"
|
||||
import { z } from "zod"
|
||||
|
||||
import { zodValidator } from "../../zod/zod-helpers"
|
||||
import { MedusaRequest, MedusaResponse } from "../types"
|
||||
@@ -79,7 +79,7 @@ export function validateAndTransformQuery<TEntity extends BaseEntity>(
|
||||
|
||||
req.validatedQuery = validated
|
||||
req.filterableFields = getFilterableFields(req.validatedQuery)
|
||||
req.remoteQueryConfig = cnf.remoteQueryConfig
|
||||
req.remoteQueryConfig = cnf.remoteQueryConfig as any
|
||||
req.listConfig = (cnf as any).listConfig
|
||||
req.retrieveConfig = (cnf as any).retrieveConfig
|
||||
|
||||
|
||||
@@ -47,6 +47,19 @@ export interface AdminOrderChangeAction
|
||||
|
||||
export interface AdminOrderFulfillment extends BaseOrderFulfillment {}
|
||||
|
||||
export interface AdminOrderItem {
|
||||
order_id: string
|
||||
item_id: string
|
||||
version: number
|
||||
history: {
|
||||
version: {
|
||||
from: number
|
||||
to: number
|
||||
}
|
||||
}
|
||||
item: AdminOrderLineItem
|
||||
}
|
||||
|
||||
export interface AdminOrderLineItem
|
||||
extends Omit<BaseOrderLineItem, "variant" | "product"> {
|
||||
variant?: AdminProductVariant
|
||||
|
||||
@@ -15,3 +15,10 @@ export interface AdminOrderFilters extends FindParams, BaseOrderFilters {
|
||||
}
|
||||
|
||||
export interface AdminOrderChangesFilters extends BaseOrderChangesFilters {}
|
||||
|
||||
export interface AdminOrderItemsFilters extends FindParams {
|
||||
id?: string[] | string
|
||||
item_id?: string[] | string
|
||||
order_id?: string[] | string
|
||||
version?: number[] | number
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { PaginatedResponse } from "../../common"
|
||||
import { AdminOrder, AdminOrderChange, AdminOrderPreview } from "./entities"
|
||||
import {
|
||||
AdminOrder,
|
||||
AdminOrderChange,
|
||||
AdminOrderItem,
|
||||
AdminOrderPreview,
|
||||
} from "./entities"
|
||||
|
||||
export interface AdminOrderResponse {
|
||||
order: AdminOrder
|
||||
@@ -13,6 +18,10 @@ export type AdminOrderListResponse = PaginatedResponse<{
|
||||
orders: AdminOrder[]
|
||||
}>
|
||||
|
||||
export type AdminOrderLineItemsListResponse = {
|
||||
order_items: AdminOrderItem[]
|
||||
}
|
||||
|
||||
export interface AdminOrderPreviewResponse {
|
||||
order: AdminOrderPreview
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "@medusajs/framework/http"
|
||||
import { HttpTypes } from "@medusajs/framework/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
deduplicate,
|
||||
} from "@medusajs/framework/utils"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminOrderItemsFilters>,
|
||||
res: MedusaResponse<HttpTypes.AdminOrderLineItemsListResponse>
|
||||
) => {
|
||||
const { id } = req.params
|
||||
|
||||
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
||||
|
||||
const result = await query.graph({
|
||||
entity: "order_items",
|
||||
filters: {
|
||||
...req.filterableFields,
|
||||
order_id: id,
|
||||
},
|
||||
fields: deduplicate(
|
||||
req.remoteQueryConfig.fields.concat(["item_id", "version"])
|
||||
),
|
||||
})
|
||||
|
||||
const data = result.data
|
||||
const deduplicatedItems = {}
|
||||
|
||||
for (const item of data) {
|
||||
const itemId = item.item_id
|
||||
const version = item.version
|
||||
|
||||
if (!deduplicatedItems[itemId]) {
|
||||
deduplicatedItems[itemId] = {
|
||||
...item,
|
||||
history: {
|
||||
version: {
|
||||
from: version,
|
||||
to: version,
|
||||
},
|
||||
},
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
deduplicatedItems[itemId].history.version.to = Math.max(
|
||||
version,
|
||||
deduplicatedItems[itemId].history.version.to
|
||||
)
|
||||
|
||||
deduplicatedItems[itemId].history.version.from = Math.min(
|
||||
version,
|
||||
deduplicatedItems[itemId].history.version.from
|
||||
)
|
||||
|
||||
if (version > deduplicatedItems[itemId].version) {
|
||||
deduplicatedItems[itemId] = {
|
||||
...item,
|
||||
history: deduplicatedItems[itemId].history,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.json({
|
||||
order_items: Object.values(deduplicatedItems),
|
||||
})
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
import { getOrderDetailWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/framework/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "@medusajs/framework/http"
|
||||
import { HttpTypes } from "@medusajs/framework/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { AdminGetOrdersOrderParamsType } from "../validators"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
req: AuthenticatedMedusaRequest<AdminGetOrdersOrderParamsType>,
|
||||
res: MedusaResponse<HttpTypes.AdminOrderResponse>
|
||||
) => {
|
||||
const workflow = getOrderDetailWorkflow(req.scope)
|
||||
@@ -18,6 +19,7 @@ export const GET = async (
|
||||
input: {
|
||||
fields: req.remoteQueryConfig.fields,
|
||||
order_id: req.params.id,
|
||||
version: req.validatedQuery.version as number,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { MiddlewareRoute } from "@medusajs/framework/http"
|
||||
import {
|
||||
validateAndTransformBody,
|
||||
validateAndTransformQuery,
|
||||
} from "@medusajs/framework"
|
||||
import { MiddlewareRoute } from "@medusajs/framework/http"
|
||||
import * as QueryConfig from "./query-config"
|
||||
import {
|
||||
AdminCompleteOrder,
|
||||
AdminGetOrdersOrderItemsParams,
|
||||
AdminGetOrdersOrderParams,
|
||||
AdminGetOrdersParams,
|
||||
AdminMarkOrderFulfillmentDelivered,
|
||||
@@ -36,6 +37,16 @@ export const adminOrderRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/orders/:id/line-items",
|
||||
middlewares: [
|
||||
validateAndTransformQuery(
|
||||
AdminGetOrdersOrderItemsParams,
|
||||
QueryConfig.listOrderItemsQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/orders/:id/changes",
|
||||
|
||||
@@ -81,6 +81,14 @@ export const defaultAdminRetrieveOrderChangesFields = [
|
||||
"updated_at",
|
||||
]
|
||||
|
||||
export const defaultAdminOrderItemsFields = [
|
||||
"id",
|
||||
"order_id",
|
||||
"item_id",
|
||||
"version",
|
||||
"*item",
|
||||
]
|
||||
|
||||
export const retrieveTransformQueryConfig = {
|
||||
defaults: defaultAdminRetrieveOrderFields,
|
||||
isList: false,
|
||||
@@ -96,3 +104,9 @@ export const retrieveOrderChangesTransformQueryConfig = {
|
||||
defaults: defaultAdminRetrieveOrderChangesFields,
|
||||
isList: false,
|
||||
}
|
||||
|
||||
export const listOrderItemsQueryConfig = {
|
||||
defaults: defaultAdminOrderItemsFields,
|
||||
defaultLimit: 100,
|
||||
isList: true,
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ export const AdminGetOrdersOrderParams = createSelectParams().merge(
|
||||
z.object({
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
status: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
version: z.number().optional(),
|
||||
created_at: createOperatorMap().optional(),
|
||||
updated_at: createOperatorMap().optional(),
|
||||
deleted_at: createOperatorMap().optional(),
|
||||
@@ -20,6 +21,18 @@ export type AdminGetOrdersOrderParamsType = z.infer<
|
||||
typeof AdminGetOrdersOrderParams
|
||||
>
|
||||
|
||||
export const AdminGetOrdersOrderItemsParams = createSelectParams().merge(
|
||||
z.object({
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
item_id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
version: z.number().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export type AdminGetOrdersOrderItemsParamsType = z.infer<
|
||||
typeof AdminGetOrdersOrderParams
|
||||
>
|
||||
|
||||
/**
|
||||
* Parameters used to filter and configure the pagination of the retrieved order.
|
||||
*/
|
||||
|
||||
@@ -32,7 +32,7 @@ declare global {
|
||||
fields: string[]
|
||||
pagination: {
|
||||
order?: Record<string, string>
|
||||
skip?: number
|
||||
skip: number
|
||||
take?: number
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IOrderModuleService } from "@medusajs/framework/types"
|
||||
import { Module, Modules } from "@medusajs/framework/utils"
|
||||
import { OrderModuleService } from "@services"
|
||||
import { moduleIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { OrderModuleService } from "@services"
|
||||
|
||||
moduleIntegrationTestRunner<IOrderModuleService>({
|
||||
moduleName: Modules.ORDER,
|
||||
@@ -18,6 +18,7 @@ moduleIntegrationTestRunner<IOrderModuleService>({
|
||||
"orderChange",
|
||||
"orderClaim",
|
||||
"orderExchange",
|
||||
"orderItem",
|
||||
"orderLineItem",
|
||||
"orderShippingMethod",
|
||||
"orderTransaction",
|
||||
@@ -89,6 +90,15 @@ moduleIntegrationTestRunner<IOrderModuleService>({
|
||||
field: "orderExchange",
|
||||
},
|
||||
},
|
||||
orderItem: {
|
||||
id: {
|
||||
linkable: "order_item_id",
|
||||
entity: "OrderItem",
|
||||
primaryKey: "id",
|
||||
serviceName: "order",
|
||||
field: "orderItem",
|
||||
},
|
||||
},
|
||||
orderLineItem: {
|
||||
id: {
|
||||
linkable: "order_line_item_id",
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
OrderChange,
|
||||
OrderClaim,
|
||||
OrderExchange,
|
||||
OrderItem,
|
||||
OrderLineItem,
|
||||
OrderShippingMethod,
|
||||
OrderTransaction,
|
||||
@@ -25,6 +26,7 @@ export const joinerConfig = defineJoinerConfig(Modules.ORDER, {
|
||||
OrderChange,
|
||||
OrderClaim,
|
||||
OrderExchange,
|
||||
OrderItem,
|
||||
OrderLineItem,
|
||||
OrderShippingMethod,
|
||||
OrderTransaction,
|
||||
|
||||
Reference in New Issue
Block a user