feat(core-flows,medusa,types): create/update workflows to create and update PriceList prices (#6711)

what:

- create and update workflows for price list prices
- update price list endpoint does a "set"
This commit is contained in:
Riqwan Thamir
2024-03-18 14:14:28 +00:00
committed by GitHub
parent 84b8836cbf
commit 0c705d7bd4
28 changed files with 509 additions and 206 deletions
@@ -0,0 +1,38 @@
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 })
}
@@ -0,0 +1,37 @@
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 })
}
@@ -1,68 +0,0 @@
import {
removePriceListPricesWorkflow,
upsertPriceListPricesWorkflow,
} from "@medusajs/core-flows"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
import { listPriceLists } from "../../queries"
import {
adminPriceListRemoteQueryFields,
defaultAdminPriceListFields,
} from "../../query-config"
import {
AdminDeletePriceListsPriceListPricesReq,
AdminPostPriceListsPriceListPricesReq,
} from "../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostPriceListsPriceListPricesReq>,
res: MedusaResponse
) => {
const { prices } = req.validatedBody
const id = req.params.id
const workflow = upsertPriceListPricesWorkflow(req.scope)
const { errors } = await workflow.run({
input: {
price_lists_data: [{ id, prices }],
},
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const [[priceList]] = await listPriceLists({
container: req.scope,
remoteQueryFields: adminPriceListRemoteQueryFields,
apiFields: defaultAdminPriceListFields,
variables: { filters: { id }, skip: 0, take: 1 },
})
res.status(200).json({ price_list: priceList })
}
export const DELETE = async (
req: AuthenticatedMedusaRequest<AdminDeletePriceListsPriceListPricesReq>,
res: MedusaResponse
) => {
const { ids } = req.validatedBody
const workflow = removePriceListPricesWorkflow(req.scope)
const { errors } = await workflow.run({
input: { ids },
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
res.status(200).json({
ids,
object: "price_list_prices",
deleted: true,
})
}
@@ -2,12 +2,11 @@ import {
deletePriceListsWorkflow,
updatePriceListsWorkflow,
} from "@medusajs/core-flows"
import { MedusaError } from "@medusajs/utils"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../types/routing"
import { listPriceLists } from "../queries"
import { getPriceList } from "../queries"
import {
adminPriceListRemoteQueryFields,
defaultAdminPriceListFields,
@@ -19,24 +18,13 @@ export const GET = async (
res: MedusaResponse
) => {
const id = req.params.id
const [[priceList], count] = await listPriceLists({
const priceList = await getPriceList({
id,
container: req.scope,
remoteQueryFields: adminPriceListRemoteQueryFields,
apiFields: req.retrieveConfig.select!,
variables: {
filters: { id },
skip: 0,
take: 1,
},
})
if (count === 0) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Price list with id: ${id} was not found`
)
}
res.status(200).json({ price_list: priceList })
}
@@ -56,11 +44,11 @@ export const POST = async (
throw errors[0].error
}
const [[priceList]] = await listPriceLists({
const priceList = await getPriceList({
id,
container: req.scope,
remoteQueryFields: adminPriceListRemoteQueryFields,
apiFields: defaultAdminPriceListFields,
variables: { filters: { id }, skip: 0, take: 1 },
})
res.status(200).json({ price_list: priceList })
@@ -3,10 +3,10 @@ import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
import * as QueryConfig from "./query-config"
import {
AdminDeletePriceListsPriceListPricesReq,
AdminGetPriceListsParams,
AdminGetPriceListsPriceListParams,
AdminPostPriceListsPriceListPricesReq,
AdminPostPriceListsPriceListPricesBatchAddReq,
AdminPostPriceListsPriceListPricesBatchRemoveReq,
AdminPostPriceListsPriceListReq,
AdminPostPriceListsReq,
} from "./validators"
@@ -49,12 +49,14 @@ export const adminPriceListsRoutesMiddlewares: MiddlewareRoute[] = [
},
{
method: ["POST"],
matcher: "/admin/price-lists/:id/prices",
middlewares: [transformBody(AdminPostPriceListsPriceListPricesReq)],
matcher: "/admin/price-lists/:id/prices/batch/add",
middlewares: [transformBody(AdminPostPriceListsPriceListPricesBatchAddReq)],
},
{
method: ["DELETE"],
matcher: "/admin/price-lists/:id/prices",
middlewares: [transformBody(AdminDeletePriceListsPriceListPricesReq)],
method: ["POST"],
matcher: "/admin/price-lists/:id/prices/batch/remove",
middlewares: [
transformBody(AdminPostPriceListsPriceListPricesBatchRemoveReq),
],
},
]
@@ -0,0 +1,40 @@
import { MedusaContainer } from "@medusajs/types"
import {
ContainerRegistrationKeys,
MedusaError,
isPresent,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { AdminPriceListRemoteQueryDTO } from "../types"
import { buildPriceListResponse } from "./"
export async function getPriceList({
id,
container,
remoteQueryFields,
apiFields,
}: {
id: string
container: MedusaContainer
remoteQueryFields: string[]
apiFields: string[]
}): Promise<AdminPriceListRemoteQueryDTO> {
const remoteQuery = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const queryObject = remoteQueryObjectFromString({
entryPoint: "price_list",
fields: remoteQueryFields,
variables: { id },
})
const priceLists = await remoteQuery(queryObject)
const [sanitizedPriceList] = buildPriceListResponse(priceLists, apiFields)
if (!isPresent(sanitizedPriceList)) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Price list with id: ${id} was not found`
)
}
return sanitizedPriceList
}
@@ -1 +1,23 @@
import {
buildPriceListRules,
buildPriceSetPricesForCore,
} from "@medusajs/utils"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import { AdminPriceListRemoteQueryDTO } from "../types"
export * from "./get-price-list"
export * from "./list-price-lists"
export function buildPriceListResponse(
priceLists,
apiFields
): AdminPriceListRemoteQueryDTO[] {
for (const priceList of priceLists) {
priceList.rules = buildPriceListRules(priceList.price_list_rules || [])
priceList.prices = buildPriceSetPricesForCore(
priceList.price_set_money_amounts || []
)
}
return priceLists.map((priceList) => cleanResponseData(priceList, apiFields))
}
@@ -1,12 +1,10 @@
import { MedusaContainer } from "@medusajs/types"
import {
ContainerRegistrationKeys,
buildPriceListRules,
buildPriceSetPricesForCore,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import { AdminPriceListRemoteQueryDTO } from "../types"
import { buildPriceListResponse } from "./"
export async function listPriceLists({
container,
@@ -32,16 +30,7 @@ export async function listPriceLists({
return [[], 0]
}
for (const priceList of priceLists) {
priceList.rules = buildPriceListRules(priceList.price_list_rules || [])
priceList.prices = buildPriceSetPricesForCore(
priceList.price_set_money_amounts || []
)
}
const sanitizedPriceLists: AdminPriceListRemoteQueryDTO[] = priceLists.map(
(priceList) => cleanResponseData(priceList, apiFields)
)
const sanitizedPriceLists = buildPriceListResponse(priceLists, apiFields)
return [sanitizedPriceLists, metadata.count]
}
@@ -98,21 +98,20 @@ export class AdminPostPriceListsPriceListReq {
@IsOptional()
@IsArray()
prices: (AdminPriceListPricesCreateReq | AdminPriceListPricesUpdateReq)[]
prices: AdminPriceListPricesCreateReq[]
@IsOptional()
@IsObject()
rules?: Record<string, string[]>
}
export class AdminPostPriceListsPriceListPricesReq {
export class AdminPostPriceListsPriceListPricesBatchAddReq {
@IsOptional()
@IsArray()
prices: (AdminPriceListPricesCreateReq | AdminPriceListPricesUpdateReq)[]
prices: AdminPriceListPricesCreateReq[]
}
export class AdminDeletePriceListsPriceListPricesReq {
@IsOptional()
export class AdminPostPriceListsPriceListPricesBatchRemoveReq {
@IsArray()
@IsString({ each: true })
ids: string[]