feat(pricing,medusa,utils): added list + get endpoints for price lists (#6592)
what: - brings back price list GET endpoints to v2 endpoints
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../types/routing"
|
||||
import { listPriceLists } from "../utils"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const id = req.params.id
|
||||
const [[priceList], count] = await listPriceLists({
|
||||
container: req.scope,
|
||||
fields: 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 })
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { transformQuery } from "../../../api/middlewares"
|
||||
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||
import * as QueryConfig from "./query-config"
|
||||
import {
|
||||
AdminGetPriceListsParams,
|
||||
AdminGetPriceListsPriceListParams,
|
||||
} from "./validators"
|
||||
|
||||
export const adminPriceListsRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/price-lists",
|
||||
middlewares: [
|
||||
transformQuery(
|
||||
AdminGetPriceListsParams,
|
||||
QueryConfig.adminListTransformQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/price-lists/:id",
|
||||
middlewares: [
|
||||
transformQuery(
|
||||
AdminGetPriceListsPriceListParams,
|
||||
QueryConfig.adminRetrieveTransformQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,65 @@
|
||||
export enum PriceListRelations {
|
||||
CUSTOMER_GROUPS = "customer_groups",
|
||||
PRICES = "prices",
|
||||
}
|
||||
|
||||
export const priceListRemoteQueryFields = {
|
||||
fields: [
|
||||
"id",
|
||||
"type",
|
||||
"description",
|
||||
"title",
|
||||
"status",
|
||||
"starts_at",
|
||||
"ends_at",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"deleted_at",
|
||||
],
|
||||
pricesFields: [
|
||||
"price_set_money_amounts.money_amount.id",
|
||||
"price_set_money_amounts.money_amount.currency_code",
|
||||
"price_set_money_amounts.money_amount.amount",
|
||||
"price_set_money_amounts.money_amount.min_quantity",
|
||||
"price_set_money_amounts.money_amount.max_quantity",
|
||||
"price_set_money_amounts.money_amount.created_at",
|
||||
"price_set_money_amounts.money_amount.deleted_at",
|
||||
"price_set_money_amounts.money_amount.updated_at",
|
||||
"price_set_money_amounts.price_set.variant.id",
|
||||
"price_set_money_amounts.price_rules.value",
|
||||
"price_set_money_amounts.price_rules.rule_type.rule_attribute",
|
||||
],
|
||||
customerGroupsFields: [
|
||||
"price_list_rules.price_list_rule_values.value",
|
||||
"price_list_rules.rule_type.rule_attribute",
|
||||
"price_set_money_amounts.price_rules.value",
|
||||
"price_set_money_amounts.price_rules.rule_type.rule_attribute",
|
||||
],
|
||||
}
|
||||
|
||||
export const defaultAdminPriceListFields = [
|
||||
...priceListRemoteQueryFields.fields,
|
||||
"name",
|
||||
]
|
||||
|
||||
export const defaultAdminPriceListRelations = []
|
||||
|
||||
export const allowedAdminPriceListRelations = [
|
||||
PriceListRelations.CUSTOMER_GROUPS,
|
||||
PriceListRelations.PRICES,
|
||||
]
|
||||
|
||||
export const adminListTransformQueryConfig = {
|
||||
defaultLimit: 50,
|
||||
defaultFields: defaultAdminPriceListFields,
|
||||
defaultRelations: defaultAdminPriceListRelations,
|
||||
allowedRelations: allowedAdminPriceListRelations,
|
||||
isList: true,
|
||||
}
|
||||
|
||||
export const adminRetrieveTransformQueryConfig = {
|
||||
defaultFields: defaultAdminPriceListFields,
|
||||
defaultRelations: defaultAdminPriceListRelations,
|
||||
allowedRelations: allowedAdminPriceListRelations,
|
||||
isList: false,
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../types/routing"
|
||||
import { listPriceLists } from "./utils"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const { limit, offset } = req.validatedQuery
|
||||
const [priceLists, count] = await listPriceLists({
|
||||
container: req.scope,
|
||||
fields: req.listConfig.select!,
|
||||
variables: {
|
||||
filters: req.filterableFields,
|
||||
order: req.listConfig.order,
|
||||
skip: req.listConfig.skip,
|
||||
take: req.listConfig.take,
|
||||
},
|
||||
})
|
||||
|
||||
res.json({
|
||||
count,
|
||||
price_lists: priceLists,
|
||||
offset,
|
||||
limit,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./list-price-lists"
|
||||
@@ -0,0 +1,123 @@
|
||||
import { LinkModuleUtils, ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { MedusaContainer, PriceListDTO } from "@medusajs/types"
|
||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
||||
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
||||
import { PriceListRelations, priceListRemoteQueryFields } from "../query-config"
|
||||
|
||||
enum RuleAttributes {
|
||||
CUSTOMER_GROUP_ID = "customer_group_id",
|
||||
REGION_ID = "region_id",
|
||||
}
|
||||
|
||||
export async function listPriceLists({
|
||||
container,
|
||||
fields,
|
||||
variables,
|
||||
}: {
|
||||
container: MedusaContainer
|
||||
fields: string[]
|
||||
variables: Record<string, any>
|
||||
}): Promise<[PriceListDTO[], number]> {
|
||||
const remoteQuery = container.resolve(LinkModuleUtils.REMOTE_QUERY)
|
||||
const customerModule = container.resolve(ModuleRegistrationName.CUSTOMER)
|
||||
|
||||
const remoteQueryFields = fields.filter(
|
||||
(field) =>
|
||||
!field.startsWith(PriceListRelations.CUSTOMER_GROUPS) &&
|
||||
!field.startsWith(PriceListRelations.PRICES)
|
||||
)
|
||||
const customerGroupFields = fields.filter((field) =>
|
||||
field.startsWith(PriceListRelations.CUSTOMER_GROUPS)
|
||||
)
|
||||
const pricesFields = fields.filter((field) =>
|
||||
field.startsWith(PriceListRelations.PRICES)
|
||||
)
|
||||
|
||||
if (customerGroupFields.length) {
|
||||
remoteQueryFields.push(...priceListRemoteQueryFields.customerGroupsFields)
|
||||
}
|
||||
|
||||
if (pricesFields.length) {
|
||||
remoteQueryFields.push(...priceListRemoteQueryFields.pricesFields)
|
||||
}
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "price_list",
|
||||
fields: remoteQueryFields,
|
||||
variables,
|
||||
})
|
||||
|
||||
const {
|
||||
rows: priceLists,
|
||||
metadata: { count },
|
||||
} = await remoteQuery(queryObject)
|
||||
|
||||
if (!count) {
|
||||
return [[], 0]
|
||||
}
|
||||
|
||||
const customerGroupIds: string[] = customerGroupFields.length
|
||||
? priceLists
|
||||
.map((priceList) => priceList.price_list_rules)
|
||||
.flat(1)
|
||||
.filter(
|
||||
(rule) =>
|
||||
rule.rule_type?.rule_attribute === RuleAttributes.CUSTOMER_GROUP_ID
|
||||
)
|
||||
.map((rule) => rule.price_list_rule_values.map((plrv) => plrv.value))
|
||||
.flat(1)
|
||||
: []
|
||||
|
||||
const customerGroups = await customerModule.listCustomerGroups(
|
||||
{ id: customerGroupIds },
|
||||
{}
|
||||
)
|
||||
|
||||
const customerGroupIdMap = new Map(customerGroups.map((cg) => [cg.id, cg]))
|
||||
|
||||
for (const priceList of priceLists) {
|
||||
const priceSetMoneyAmounts = priceList.price_set_money_amounts || []
|
||||
const priceListRulesData = priceList.price_list_rules || []
|
||||
delete priceList.price_set_money_amounts
|
||||
delete priceList.price_list_rules
|
||||
|
||||
if (pricesFields.length) {
|
||||
priceList.prices = priceSetMoneyAmounts.map((priceSetMoneyAmount) => {
|
||||
const productVariant = priceSetMoneyAmount.price_set.variant
|
||||
const rules = priceSetMoneyAmount.price_rules.reduce((acc, curr) => {
|
||||
acc[curr.rule_type.rule_attribute] = curr.value
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return {
|
||||
...priceSetMoneyAmount.money_amount,
|
||||
price_list_id: priceList.id,
|
||||
variant_id: productVariant?.id ?? null,
|
||||
region_id: rules["region_id"] ?? null,
|
||||
rules,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
priceList.name = priceList.title
|
||||
delete priceList.title
|
||||
|
||||
if (customerGroupFields.length) {
|
||||
const customerGroupPriceListRule = priceListRulesData.find(
|
||||
(plr) =>
|
||||
plr.rule_type.rule_attribute === RuleAttributes.CUSTOMER_GROUP_ID
|
||||
)
|
||||
|
||||
priceList.customer_groups =
|
||||
customerGroupPriceListRule?.price_list_rule_values
|
||||
.map((cgr) => customerGroupIdMap.get(cgr.value))
|
||||
.filter(Boolean) || []
|
||||
}
|
||||
}
|
||||
|
||||
const sanitizedPriceLists = priceLists.map((priceList) => {
|
||||
return cleanResponseData(priceList, fields)
|
||||
})
|
||||
|
||||
return [sanitizedPriceLists, count]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { FindParams } from "../../../types/common"
|
||||
|
||||
export class AdminGetPriceListsParams extends FindParams {}
|
||||
export class AdminGetPriceListsPriceListParams extends FindParams {}
|
||||
Reference in New Issue
Block a user