feat(medusa,core-flows,types): adds batch operations to price list prices (#7077)
what: - adds batch operations to price list prices RESOLVES CORE-1969 RESOLVES CORE-1970
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
import { createPriceListPricesWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../../../types/routing"
|
||||
import { getPriceList } from "../../../../queries"
|
||||
import {
|
||||
adminPriceListRemoteQueryFields,
|
||||
defaultAdminPriceListFields,
|
||||
} from "../../../../query-config"
|
||||
import { AdminPostPriceListsPriceListPricesBatchAddReq } from "../../../../validators"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminPostPriceListsPriceListPricesBatchAddReq>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const { prices } = req.validatedBody
|
||||
|
||||
const id = req.params.id
|
||||
const workflow = createPriceListPricesWorkflow(req.scope)
|
||||
const { errors } = await workflow.run({
|
||||
input: { data: [{ id, prices }] },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const priceList = await getPriceList({
|
||||
id,
|
||||
container: req.scope,
|
||||
remoteQueryFields: adminPriceListRemoteQueryFields,
|
||||
apiFields: defaultAdminPriceListFields,
|
||||
})
|
||||
|
||||
res.status(200).json({ price_list: priceList })
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { removePriceListPricesWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../../../types/routing"
|
||||
import { getPriceList } from "../../../../queries"
|
||||
import {
|
||||
adminPriceListRemoteQueryFields,
|
||||
defaultAdminPriceListFields,
|
||||
} from "../../../../query-config"
|
||||
import { AdminPostPriceListsPriceListPricesBatchRemoveReq } from "../../../../validators"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminPostPriceListsPriceListPricesBatchRemoveReq>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const { ids } = req.validatedBody
|
||||
const id = req.params.id
|
||||
const workflow = removePriceListPricesWorkflow(req.scope)
|
||||
const { errors } = await workflow.run({
|
||||
input: { ids },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const priceList = await getPriceList({
|
||||
id,
|
||||
container: req.scope,
|
||||
remoteQueryFields: adminPriceListRemoteQueryFields,
|
||||
apiFields: defaultAdminPriceListFields,
|
||||
})
|
||||
|
||||
res.status(200).json({ price_list: priceList })
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { batchPriceListPricesWorkflow } from "@medusajs/core-flows"
|
||||
import { promiseAll } from "@medusajs/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../../types/routing"
|
||||
import { fetchPriceListPriceIdsForProduct } from "../../../helpers"
|
||||
import { listPrices } from "../../../queries"
|
||||
import { adminPriceListPriceRemoteQueryFields } from "../../../query-config"
|
||||
import { AdminBatchPriceListPricesType } from "../../../validators"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminBatchPriceListPricesType>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const id = req.params.id
|
||||
const {
|
||||
create = [],
|
||||
update = [],
|
||||
delete: deletePriceIds = [],
|
||||
product_id: productIds = [],
|
||||
} = req.validatedBody
|
||||
|
||||
const productPriceIds = await fetchPriceListPriceIdsForProduct(
|
||||
id,
|
||||
productIds,
|
||||
req.scope
|
||||
)
|
||||
|
||||
const priceIdsToDelete = [...deletePriceIds, ...productPriceIds]
|
||||
const workflow = batchPriceListPricesWorkflow(req.scope)
|
||||
const { result, errors } = await workflow.run({
|
||||
input: {
|
||||
data: {
|
||||
id,
|
||||
create,
|
||||
update,
|
||||
delete: priceIdsToDelete,
|
||||
},
|
||||
},
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const [created, updated] = await promiseAll([
|
||||
listPrices(
|
||||
result.created.map((c) => c.id),
|
||||
req.scope,
|
||||
adminPriceListPriceRemoteQueryFields
|
||||
),
|
||||
listPrices(
|
||||
result.updated.map((c) => c.id),
|
||||
req.scope,
|
||||
adminPriceListPriceRemoteQueryFields
|
||||
),
|
||||
])
|
||||
|
||||
res.status(200).json({
|
||||
created,
|
||||
updated,
|
||||
deleted: {
|
||||
ids: priceIdsToDelete,
|
||||
object: "price",
|
||||
deleted: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { updatePriceListPricesWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../../../types/routing"
|
||||
import { getPriceList } from "../../../../queries"
|
||||
import {
|
||||
adminPriceListRemoteQueryFields,
|
||||
defaultAdminPriceListFields,
|
||||
} from "../../../../query-config"
|
||||
import { AdminPostPriceListPriceBatchUpdate } from "../../../../validators"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminPostPriceListPriceBatchUpdate>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const { prices } = req.validatedBody
|
||||
|
||||
const id = req.params.id
|
||||
const workflow = updatePriceListPricesWorkflow(req.scope)
|
||||
const { errors } = await workflow.run({
|
||||
input: { data: [{ id, prices }] },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const priceList = await getPriceList({
|
||||
id,
|
||||
container: req.scope,
|
||||
remoteQueryFields: adminPriceListRemoteQueryFields,
|
||||
apiFields: defaultAdminPriceListFields,
|
||||
})
|
||||
|
||||
res.status(200).json({ price_list: priceList })
|
||||
}
|
||||
@@ -6,37 +6,31 @@ import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../types/routing"
|
||||
import { getPriceList } from "../queries"
|
||||
import {
|
||||
adminPriceListRemoteQueryFields,
|
||||
defaultAdminPriceListFields,
|
||||
} from "../query-config"
|
||||
import { AdminPostPriceListsPriceListReq } from "../validators"
|
||||
import { fetchPriceList } from "../helpers"
|
||||
import { AdminUpdatePriceListType } from "../validators"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const id = req.params.id
|
||||
const priceList = await getPriceList({
|
||||
id,
|
||||
container: req.scope,
|
||||
remoteQueryFields: adminPriceListRemoteQueryFields,
|
||||
apiFields: req.retrieveConfig.select!,
|
||||
})
|
||||
const price_list = await fetchPriceList(
|
||||
req.params.id,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
)
|
||||
|
||||
res.status(200).json({ price_list: priceList })
|
||||
res.status(200).json({ price_list })
|
||||
}
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminPostPriceListsPriceListReq>,
|
||||
req: AuthenticatedMedusaRequest<AdminUpdatePriceListType>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const id = req.params.id
|
||||
const workflow = updatePriceListsWorkflow(req.scope)
|
||||
|
||||
const { errors } = await workflow.run({
|
||||
input: { price_lists_data: [{ id, ...req.validatedBody }] },
|
||||
input: { price_lists_data: [{ ...req.validatedBody, id }] },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
@@ -44,14 +38,13 @@ export const POST = async (
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const priceList = await getPriceList({
|
||||
const price_list = await fetchPriceList(
|
||||
id,
|
||||
container: req.scope,
|
||||
remoteQueryFields: adminPriceListRemoteQueryFields,
|
||||
apiFields: defaultAdminPriceListFields,
|
||||
})
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
)
|
||||
|
||||
res.status(200).json({ price_list: priceList })
|
||||
res.status(200).json({ price_list })
|
||||
}
|
||||
|
||||
export const DELETE = async (
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import {
|
||||
buildPriceListRules,
|
||||
buildPriceSetPricesForCore,
|
||||
ContainerRegistrationKeys,
|
||||
isPresent,
|
||||
MedusaError,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
export const fetchPriceList = async (
|
||||
id: string,
|
||||
scope: MedusaContainer,
|
||||
fields: string[]
|
||||
) => {
|
||||
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "price_lists",
|
||||
variables: {
|
||||
filters: { id },
|
||||
},
|
||||
fields,
|
||||
})
|
||||
|
||||
const [priceList] = await remoteQuery(queryObject)
|
||||
|
||||
if (!isPresent(priceList)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_FOUND,
|
||||
`Price list with id: ${id} was not found`
|
||||
)
|
||||
}
|
||||
|
||||
return transformPriceList(priceList)
|
||||
}
|
||||
|
||||
export const transformPriceList = (priceList) => {
|
||||
priceList.rules = buildPriceListRules(priceList.price_list_rules)
|
||||
priceList.prices = buildPriceSetPricesForCore(priceList.prices)
|
||||
|
||||
delete priceList.price_list_rules
|
||||
|
||||
return priceList
|
||||
}
|
||||
|
||||
export const fetchPriceListPriceIdsForProduct = async (
|
||||
priceListId: string,
|
||||
productIds: string[],
|
||||
scope: MedusaContainer
|
||||
): Promise<string[]> => {
|
||||
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const priceSetIds: string[] = []
|
||||
const variants = await remoteQuery(
|
||||
remoteQueryObjectFromString({
|
||||
entryPoint: "variants",
|
||||
variables: { filters: { product_id: productIds } },
|
||||
fields: ["price_set.id"],
|
||||
})
|
||||
)
|
||||
|
||||
for (const variant of variants) {
|
||||
if (variant.price_set?.id) {
|
||||
priceSetIds.push(variant.price_set.id)
|
||||
}
|
||||
}
|
||||
|
||||
const productPrices = await remoteQuery(
|
||||
remoteQueryObjectFromString({
|
||||
entryPoint: "prices",
|
||||
variables: {
|
||||
filters: { price_set_id: priceSetIds, price_list_id: priceListId },
|
||||
},
|
||||
fields: ["id"],
|
||||
})
|
||||
)
|
||||
|
||||
return productPrices.map((price) => price.id)
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
import { transformBody, transformQuery } from "../../../api/middlewares"
|
||||
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||
import { authenticate } from "../../../utils/authenticate-middleware"
|
||||
import { validateAndTransformBody } from "../../utils/validate-body"
|
||||
import { validateAndTransformQuery } from "../../utils/validate-query"
|
||||
import * as QueryConfig from "./query-config"
|
||||
import {
|
||||
AdminBatchPriceListPrices,
|
||||
AdminCreatePriceList,
|
||||
AdminGetPriceListParams,
|
||||
AdminGetPriceListPricesParams,
|
||||
AdminGetPriceListsParams,
|
||||
AdminGetPriceListsPriceListParams,
|
||||
AdminPostPriceListPriceBatchUpdate,
|
||||
AdminPostPriceListsPriceListPricesBatchAddReq,
|
||||
AdminPostPriceListsPriceListPricesBatchRemoveReq,
|
||||
AdminPostPriceListsPriceListReq,
|
||||
AdminPostPriceListsReq,
|
||||
AdminUpdatePriceList,
|
||||
} from "./validators"
|
||||
|
||||
export const adminPriceListsRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
@@ -22,9 +22,9 @@ export const adminPriceListsRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
method: ["GET"],
|
||||
matcher: "/admin/price-lists",
|
||||
middlewares: [
|
||||
transformQuery(
|
||||
validateAndTransformQuery(
|
||||
AdminGetPriceListsParams,
|
||||
QueryConfig.adminListTransformQueryConfig
|
||||
QueryConfig.listPriceListQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
@@ -32,37 +32,43 @@ export const adminPriceListsRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
method: ["GET"],
|
||||
matcher: "/admin/price-lists/:id",
|
||||
middlewares: [
|
||||
transformQuery(
|
||||
AdminGetPriceListsPriceListParams,
|
||||
QueryConfig.adminRetrieveTransformQueryConfig
|
||||
validateAndTransformQuery(
|
||||
AdminGetPriceListParams,
|
||||
QueryConfig.retrivePriceListQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/price-lists",
|
||||
middlewares: [transformBody(AdminPostPriceListsReq)],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/price-lists/:id",
|
||||
middlewares: [transformBody(AdminPostPriceListsPriceListReq)],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/price-lists/:id/prices/batch/add",
|
||||
middlewares: [transformBody(AdminPostPriceListsPriceListPricesBatchAddReq)],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/price-lists/:id/prices/batch/remove",
|
||||
middlewares: [
|
||||
transformBody(AdminPostPriceListsPriceListPricesBatchRemoveReq),
|
||||
validateAndTransformBody(AdminCreatePriceList),
|
||||
validateAndTransformQuery(
|
||||
AdminGetPriceListPricesParams,
|
||||
QueryConfig.retrivePriceListQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/price-lists/:id/prices/batch/update",
|
||||
middlewares: [transformBody(AdminPostPriceListPriceBatchUpdate)],
|
||||
matcher: "/admin/price-lists/:id",
|
||||
middlewares: [
|
||||
validateAndTransformBody(AdminUpdatePriceList),
|
||||
validateAndTransformQuery(
|
||||
AdminGetPriceListPricesParams,
|
||||
QueryConfig.retrivePriceListQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/price-lists/:id/prices/batch",
|
||||
middlewares: [
|
||||
validateAndTransformBody(AdminBatchPriceListPrices),
|
||||
validateAndTransformQuery(
|
||||
AdminGetPriceListPricesParams,
|
||||
QueryConfig.listPriceListPriceQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -7,14 +7,15 @@ import { AdminPriceListRemoteQueryDTO } from "../types"
|
||||
|
||||
export * from "./get-price-list"
|
||||
export * from "./list-price-lists"
|
||||
export * from "./list-prices"
|
||||
|
||||
export function buildPriceListResponse(
|
||||
priceLists,
|
||||
apiFields
|
||||
): AdminPriceListRemoteQueryDTO[] {
|
||||
for (const priceList of priceLists) {
|
||||
priceList.rules = buildPriceListRules(priceList.price_list_rules || [])
|
||||
priceList.prices = buildPriceSetPricesForCore(priceList.prices || [])
|
||||
priceList.rules = buildPriceListRules(priceList.price_list_rules)
|
||||
priceList.prices = buildPriceSetPricesForCore(priceList.prices)
|
||||
}
|
||||
|
||||
return priceLists.map((priceList) => cleanResponseData(priceList, apiFields))
|
||||
|
||||
@@ -4,17 +4,14 @@ import {
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { AdminPriceListRemoteQueryDTO } from "../types"
|
||||
import { buildPriceListResponse } from "./"
|
||||
|
||||
export async function listPriceLists({
|
||||
container,
|
||||
remoteQueryFields,
|
||||
apiFields,
|
||||
variables,
|
||||
}: {
|
||||
container: MedusaContainer
|
||||
remoteQueryFields: string[]
|
||||
apiFields: string[]
|
||||
variables: Record<string, any>
|
||||
}): Promise<[AdminPriceListRemoteQueryDTO[], number]> {
|
||||
const remoteQuery = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
@@ -26,11 +23,5 @@ export async function listPriceLists({
|
||||
|
||||
const { rows: priceLists, metadata } = await remoteQuery(queryObject)
|
||||
|
||||
if (!metadata.count) {
|
||||
return [[], 0]
|
||||
}
|
||||
|
||||
const sanitizedPriceLists = buildPriceListResponse(priceLists, apiFields)
|
||||
|
||||
return [sanitizedPriceLists, metadata.count]
|
||||
return [priceLists, metadata.count]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
export const listPrices = (
|
||||
ids: string[],
|
||||
scope: MedusaContainer,
|
||||
fields: string[]
|
||||
) => {
|
||||
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "price",
|
||||
variables: {
|
||||
filters: { id: ids },
|
||||
},
|
||||
fields,
|
||||
})
|
||||
|
||||
return remoteQuery(queryObject)
|
||||
}
|
||||
@@ -2,6 +2,20 @@ export enum PriceListRelations {
|
||||
PRICES = "prices",
|
||||
}
|
||||
|
||||
export const adminPriceListPriceRemoteQueryFields = [
|
||||
"id",
|
||||
"currency_code",
|
||||
"amount",
|
||||
"min_quantity",
|
||||
"max_quantity",
|
||||
"created_at",
|
||||
"deleted_at",
|
||||
"updated_at",
|
||||
"price_set.variant.id",
|
||||
"price_rules.value",
|
||||
"price_rules.rule_type.rule_attribute",
|
||||
]
|
||||
|
||||
export const adminPriceListRemoteQueryFields = [
|
||||
"id",
|
||||
"type",
|
||||
@@ -13,56 +27,27 @@ export const adminPriceListRemoteQueryFields = [
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
"prices.id",
|
||||
"prices.currency_code",
|
||||
"prices.amount",
|
||||
"prices.min_quantity",
|
||||
"prices.max_quantity",
|
||||
"prices.created_at",
|
||||
"prices.deleted_at",
|
||||
"prices.updated_at",
|
||||
"prices.price_set.variant.id",
|
||||
"prices.price_rules.value",
|
||||
"prices.price_rules.rule_type.rule_attribute",
|
||||
"price_list_rules.price_list_rule_values.value",
|
||||
"price_list_rules.rule_type.rule_attribute",
|
||||
...adminPriceListPriceRemoteQueryFields.map((field) => `prices.${field}`),
|
||||
]
|
||||
|
||||
export const defaultAdminPriceListFields = [
|
||||
"id",
|
||||
"type",
|
||||
"description",
|
||||
"title",
|
||||
"status",
|
||||
"starts_at",
|
||||
"ends_at",
|
||||
"rules",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"prices.amount",
|
||||
"prices.id",
|
||||
"prices.currency_code",
|
||||
"prices.amount",
|
||||
"prices.min_quantity",
|
||||
"prices.max_quantity",
|
||||
"prices.variant_id",
|
||||
"prices.rules",
|
||||
]
|
||||
export const retrivePriceListPriceQueryConfig = {
|
||||
defaults: adminPriceListPriceRemoteQueryFields,
|
||||
isList: false,
|
||||
}
|
||||
|
||||
export const defaultAdminPriceListRelations = []
|
||||
export const allowedAdminPriceListRelations = [PriceListRelations.PRICES]
|
||||
|
||||
export const adminListTransformQueryConfig = {
|
||||
defaultLimit: 50,
|
||||
defaultFields: defaultAdminPriceListFields,
|
||||
defaultRelations: defaultAdminPriceListRelations,
|
||||
allowedRelations: allowedAdminPriceListRelations,
|
||||
export const listPriceListPriceQueryConfig = {
|
||||
...retrivePriceListPriceQueryConfig,
|
||||
isList: true,
|
||||
}
|
||||
|
||||
export const adminRetrieveTransformQueryConfig = {
|
||||
defaultFields: defaultAdminPriceListFields,
|
||||
defaultRelations: defaultAdminPriceListRelations,
|
||||
allowedRelations: allowedAdminPriceListRelations,
|
||||
export const retrivePriceListQueryConfig = {
|
||||
defaults: adminPriceListRemoteQueryFields,
|
||||
isList: false,
|
||||
}
|
||||
|
||||
export const listPriceListQueryConfig = {
|
||||
...retrivePriceListQueryConfig,
|
||||
isList: true,
|
||||
}
|
||||
|
||||
@@ -1,42 +1,43 @@
|
||||
import { createPriceListsWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../types/routing"
|
||||
import { listPriceLists } from "./queries"
|
||||
import {
|
||||
adminPriceListRemoteQueryFields,
|
||||
defaultAdminPriceListFields,
|
||||
} from "./query-config"
|
||||
import { AdminPostPriceListsReq } from "./validators"
|
||||
import { fetchPriceList, transformPriceList } from "./helpers"
|
||||
import { AdminCreatePriceListType } from "./validators"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const { limit, offset } = req.validatedQuery
|
||||
const [priceLists, count] = await listPriceLists({
|
||||
container: req.scope,
|
||||
apiFields: req.listConfig.select!,
|
||||
remoteQueryFields: adminPriceListRemoteQueryFields,
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "price_list",
|
||||
variables: {
|
||||
filters: req.filterableFields,
|
||||
order: req.listConfig.order,
|
||||
skip: req.listConfig.skip,
|
||||
take: req.listConfig.take,
|
||||
...req.remoteQueryConfig.pagination,
|
||||
},
|
||||
fields: req.remoteQueryConfig.fields,
|
||||
})
|
||||
|
||||
const { rows: priceLists, metadata } = await remoteQuery(queryObject)
|
||||
|
||||
res.json({
|
||||
count,
|
||||
price_lists: priceLists,
|
||||
count: metadata.count,
|
||||
price_lists: priceLists.map((priceList) => transformPriceList(priceList)),
|
||||
offset,
|
||||
limit,
|
||||
})
|
||||
}
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminPostPriceListsReq>,
|
||||
req: AuthenticatedMedusaRequest<AdminCreatePriceListType>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const workflow = createPriceListsWorkflow(req.scope)
|
||||
@@ -49,16 +50,11 @@ export const POST = async (
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const [[priceList]] = await listPriceLists({
|
||||
container: req.scope,
|
||||
apiFields: defaultAdminPriceListFields,
|
||||
remoteQueryFields: adminPriceListRemoteQueryFields,
|
||||
variables: {
|
||||
filters: { id: result[0].id },
|
||||
skip: 0,
|
||||
take: 1,
|
||||
},
|
||||
})
|
||||
const price_list = await fetchPriceList(
|
||||
result[0].id,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
)
|
||||
|
||||
res.status(200).json({ price_list: priceList })
|
||||
res.status(200).json({ price_list })
|
||||
}
|
||||
|
||||
@@ -1,151 +1,77 @@
|
||||
import { PriceListStatus, PriceListType } from "@medusajs/types"
|
||||
import { Transform, Type } from "class-transformer"
|
||||
import {
|
||||
IsArray,
|
||||
IsEnum,
|
||||
IsInt,
|
||||
IsObject,
|
||||
IsOptional,
|
||||
IsString,
|
||||
ValidateNested,
|
||||
} from "class-validator"
|
||||
import { FindParams } from "../../../types/common"
|
||||
import { transformOptionalDate } from "../../../utils/validators/date-transform"
|
||||
import { z } from "zod"
|
||||
import { createFindParams, createSelectParams } from "../../utils/validators"
|
||||
|
||||
export class AdminGetPriceListsParams extends FindParams {}
|
||||
export class AdminGetPriceListsPriceListParams extends FindParams {}
|
||||
export const AdminGetPriceListPricesParams = createSelectParams()
|
||||
export const AdminGetPriceListsParams = createFindParams({
|
||||
offset: 0,
|
||||
limit: 50,
|
||||
})
|
||||
|
||||
export class AdminPostPriceListsReq {
|
||||
@IsString()
|
||||
title: string
|
||||
export const AdminGetPriceListParams = createFindParams({
|
||||
offset: 0,
|
||||
limit: 50,
|
||||
})
|
||||
|
||||
@IsString()
|
||||
description: string
|
||||
export const AdminCreatePriceListPrice = z.object({
|
||||
currency_code: z.string(),
|
||||
amount: z.number(),
|
||||
variant_id: z.string(),
|
||||
min_quantity: z.number().optional(),
|
||||
max_quantity: z.number().optional(),
|
||||
rules: z.record(z.string(), z.string()).optional(),
|
||||
})
|
||||
|
||||
@IsOptional()
|
||||
@Transform(transformOptionalDate)
|
||||
starts_at?: string
|
||||
export type AdminCreatePriceListPriceType = z.infer<
|
||||
typeof AdminCreatePriceListPrice
|
||||
>
|
||||
|
||||
@IsOptional()
|
||||
@Transform(transformOptionalDate)
|
||||
ends_at?: string
|
||||
export const AdminUpdatePriceListPrice = z.object({
|
||||
id: z.string(),
|
||||
currency_code: z.string().optional(),
|
||||
amount: z.number().optional(),
|
||||
variant_id: z.string(),
|
||||
min_quantity: z.number().optional(),
|
||||
max_quantity: z.number().optional(),
|
||||
rules: z.record(z.string(), z.string()).optional(),
|
||||
})
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(PriceListStatus)
|
||||
status?: PriceListStatus
|
||||
export type AdminUpdatePriceListPriceType = z.infer<
|
||||
typeof AdminUpdatePriceListPrice
|
||||
>
|
||||
|
||||
@IsEnum(PriceListType)
|
||||
type: PriceListType
|
||||
export const AdminBatchPriceListPrices = z.object({
|
||||
create: z.array(AdminCreatePriceListPrice).optional(),
|
||||
update: z.array(AdminUpdatePriceListPrice).optional(),
|
||||
delete: z.array(z.string()).optional(),
|
||||
product_id: z.array(z.string()).optional(),
|
||||
})
|
||||
|
||||
@IsArray()
|
||||
@Type(() => AdminPriceListPricesCreateReq)
|
||||
@ValidateNested({ each: true })
|
||||
prices: AdminPriceListPricesCreateReq[]
|
||||
export type AdminBatchPriceListPricesType = z.infer<
|
||||
typeof AdminBatchPriceListPrices
|
||||
>
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
rules?: Record<string, string[]>
|
||||
}
|
||||
export const AdminCreatePriceList = z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
starts_at: z.string().optional(),
|
||||
ends_at: z.string().optional(),
|
||||
status: z.nativeEnum(PriceListStatus).optional(),
|
||||
type: z.nativeEnum(PriceListType).optional(),
|
||||
rules: z.record(z.string(), z.array(z.string())).optional(),
|
||||
prices: z.array(AdminCreatePriceListPrice).optional(),
|
||||
})
|
||||
|
||||
export class AdminPriceListPricesCreateReq {
|
||||
@IsString()
|
||||
currency_code: string
|
||||
export type AdminCreatePriceListType = z.infer<typeof AdminCreatePriceList>
|
||||
|
||||
@IsInt()
|
||||
amount: number
|
||||
export const AdminUpdatePriceList = z.object({
|
||||
title: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
starts_at: z.string().optional(),
|
||||
ends_at: z.string().optional(),
|
||||
status: z.nativeEnum(PriceListStatus).optional(),
|
||||
type: z.nativeEnum(PriceListType).optional(),
|
||||
rules: z.record(z.string(), z.array(z.string())).optional(),
|
||||
})
|
||||
|
||||
@IsString()
|
||||
variant_id: string
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
min_quantity?: number
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
max_quantity?: number
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
rules?: Record<string, string>
|
||||
}
|
||||
|
||||
export class AdminPostPriceListsPriceListReq {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
title?: string
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
description?: string
|
||||
|
||||
@IsOptional()
|
||||
@Transform(transformOptionalDate)
|
||||
starts_at?: string
|
||||
|
||||
@IsOptional()
|
||||
@Transform(transformOptionalDate)
|
||||
ends_at?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(PriceListStatus)
|
||||
status?: PriceListStatus
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(PriceListType)
|
||||
type?: PriceListType
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
prices: AdminPriceListPricesCreateReq[]
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
rules?: Record<string, string[]>
|
||||
}
|
||||
|
||||
export class AdminPostPriceListsPriceListPricesBatchAddReq {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
prices: AdminPriceListPricesCreateReq[]
|
||||
}
|
||||
|
||||
export class AdminPostPriceListPriceBatchUpdate {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
prices: AdminPostPriceListPriceUpdate[]
|
||||
}
|
||||
|
||||
export class AdminPostPriceListsPriceListPricesBatchRemoveReq {
|
||||
@IsArray()
|
||||
@IsString({ each: true })
|
||||
ids: string[]
|
||||
}
|
||||
|
||||
export class AdminPostPriceListPriceUpdate {
|
||||
@IsString()
|
||||
id: string
|
||||
|
||||
@IsString()
|
||||
variant_id: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
currency_code?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
amount?: number
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
min_quantity?: number
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
max_quantity?: number
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
rules?: Record<string, string>
|
||||
}
|
||||
export type AdminUpdatePriceListType = z.infer<typeof AdminUpdatePriceList>
|
||||
|
||||
Reference in New Issue
Block a user