feat: Completely revamp the pricing module (#7852)

* feat: Completely revamp the pricing module

* chore: Update all places to the new pricing interfaces

* fix: Remove unnecessary join to itself

* chore: Add data migration for existing users

* fix: Apply the correct index to price rule
This commit is contained in:
Stevche Radevski authored and GitHub committed 2024-07-01 09:47:03 +02:00
1 parent 1f360a3245
commit c661180c44
84 files changed
+661 -3725

No files matched your search

@@ -13,7 +13,7 @@ export const adminPriceListPriceRemoteQueryFields = [
"updated_at",
"price_set.variant.id",
"price_rules.value",
"price_rules.rule_type.rule_attribute",
"price_rules.attribute",
]
export const adminPriceListRemoteQueryFields = [
@@ -27,8 +27,8 @@ export const adminPriceListRemoteQueryFields = [
"created_at",
"updated_at",
"deleted_at",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
"price_list_rules.value",
"price_list_rules.attribute",
...adminPriceListPriceRemoteQueryFields.map((field) => `prices.${field}`),
]
@@ -1,23 +0,0 @@
import { MedusaContainer } from "@medusajs/types"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
export const refetchRuleType = async (
ruleTypeId: string,
scope: MedusaContainer,
fields: string[]
) => {
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const queryObject = remoteQueryObjectFromString({
entryPoint: "rule_type",
variables: {
filters: { id: ruleTypeId },
},
fields: fields,
})
const ruleTypes = await remoteQuery(queryObject)
return ruleTypes[0]
}
@@ -1,60 +0,0 @@
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { validateAndTransformBody } from "../../utils/validate-body"
import { validateAndTransformQuery } from "../../utils/validate-query"
import * as QueryConfig from "./query-config"
import {
AdminCreatePricingRuleType,
AdminGetPricingRuleTypeParams,
AdminGetPricingRuleTypesParams,
AdminUpdatePricingRuleType,
} from "./validators"
export const adminPricingRoutesMiddlewares: MiddlewareRoute[] = [
{
method: ["GET"],
matcher: "/admin/pricing/rule-types",
middlewares: [
validateAndTransformQuery(
AdminGetPricingRuleTypesParams,
QueryConfig.listTransformQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/pricing/rule-types",
middlewares: [
validateAndTransformBody(AdminCreatePricingRuleType),
validateAndTransformQuery(
AdminGetPricingRuleTypeParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
{
method: ["GET"],
matcher: "/admin/pricing/rule-types/:id",
middlewares: [
validateAndTransformQuery(
AdminGetPricingRuleTypeParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/pricing/rule-types/:id",
middlewares: [
validateAndTransformBody(AdminUpdatePricingRuleType),
validateAndTransformQuery(
AdminGetPricingRuleTypeParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
{
method: ["DELETE"],
matcher: "/admin/pricing/rule-types/:id",
middlewares: [],
},
]
@@ -1,16 +0,0 @@
export const defaultAdminPricingRuleTypeFields = [
"id",
"name",
"rule_attribute",
"default_priority",
]
export const retrieveTransformQueryConfig = {
defaults: defaultAdminPricingRuleTypeFields,
isList: false,
}
export const listTransformQueryConfig = {
...retrieveTransformQueryConfig,
isList: true,
}
@@ -1,74 +0,0 @@
import {
deletePricingRuleTypesWorkflow,
updatePricingRuleTypesWorkflow,
} from "@medusajs/core-flows"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
import {
AdminGetPricingRuleTypeParamsType,
AdminUpdatePricingRuleTypeType,
} from "../../validators"
import { refetchRuleType } from "../../helpers"
import { MedusaError } from "@medusajs/utils"
export const GET = async (
req: AuthenticatedMedusaRequest<AdminGetPricingRuleTypeParamsType>,
res: MedusaResponse
) => {
const ruleType = await refetchRuleType(
req.params.id,
req.scope,
req.remoteQueryConfig.fields
)
if (!ruleType) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`RuleType with id: ${req.params.id} was not found`
)
}
res.status(200).json({ rule_type: ruleType })
}
export const POST = async (
req: AuthenticatedMedusaRequest<AdminUpdatePricingRuleTypeType>,
res: MedusaResponse
) => {
const workflow = updatePricingRuleTypesWorkflow(req.scope)
await workflow.run({
input: {
data: [{ ...req.validatedBody, id: req.params.id }],
},
})
const ruleType = await refetchRuleType(
req.params.id,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({
rule_type: ruleType,
})
}
export const DELETE = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse
) => {
const id = req.params.id
const workflow = deletePricingRuleTypesWorkflow(req.scope)
await workflow.run({
input: { ids: [id] },
})
res.status(200).json({
id,
object: "rule_type",
deleted: true,
})
}
@@ -1,60 +0,0 @@
import { createPricingRuleTypesWorkflow } from "@medusajs/core-flows"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../types/routing"
import {
AdminCreatePricingRuleTypeType,
AdminGetPricingRuleTypesParamsType,
} from "../validators"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { refetchRuleType } from "../helpers"
export const GET = async (
req: AuthenticatedMedusaRequest<AdminGetPricingRuleTypesParamsType>,
res: MedusaResponse
) => {
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const queryObject = remoteQueryObjectFromString({
entryPoint: "rule_type",
variables: {
filters: req.filterableFields,
...req.remoteQueryConfig.pagination,
},
fields: req.remoteQueryConfig.fields,
})
const { rows: rule_types, metadata } = await remoteQuery(queryObject)
res.json({
rule_types: rule_types,
count: metadata.count,
offset: metadata.skip,
limit: metadata.take,
})
}
export const POST = async (
req: AuthenticatedMedusaRequest<AdminCreatePricingRuleTypeType>,
res: MedusaResponse
) => {
const workflow = createPricingRuleTypesWorkflow(req.scope)
const ruleTypesData = [req.validatedBody]
const { result } = await workflow.run({
input: { data: ruleTypesData },
})
const ruleType = await refetchRuleType(
result[0].id,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({
rule_type: ruleType,
})
}
@@ -1,43 +0,0 @@
import { z } from "zod"
import { createFindParams, createSelectParams } from "../../utils/validators"
export type AdminGetPricingRuleTypeParamsType = z.infer<
typeof AdminGetPricingRuleTypeParams
>
export const AdminGetPricingRuleTypeParams = createSelectParams()
export type AdminGetPricingRuleTypesParamsType = z.infer<
typeof AdminGetPricingRuleTypesParams
>
export const AdminGetPricingRuleTypesParams = createFindParams({
limit: 100,
offset: 0,
}).merge(
z.object({
rule_attribute: z.union([z.string(), z.array(z.string())]).optional(),
$and: z.lazy(() => AdminGetPricingRuleTypesParams.array()).optional(),
$or: z.lazy(() => AdminGetPricingRuleTypesParams.array()).optional(),
})
)
export type AdminCreatePricingRuleTypeType = z.infer<
typeof AdminCreatePricingRuleType
>
export const AdminCreatePricingRuleType = z
.object({
name: z.string(),
rule_attribute: z.string(),
default_priority: z.number(),
})
.strict()
export type AdminUpdatePricingRuleTypeType = z.infer<
typeof AdminUpdatePricingRuleType
>
export const AdminUpdatePricingRuleType = z
.object({
name: z.string().optional(),
rule_attribute: z.string().optional(),
default_priority: z.number().optional(),
})
.strict()
@@ -92,7 +92,7 @@ export const buildRules = (price: PriceDTO) => {
const rules: Record<string, string> = {}
for (const priceRule of price.price_rules || []) {
const ruleAttribute = priceRule.rule_type?.rule_attribute
const ruleAttribute = priceRule.attribute
if (ruleAttribute) {
rules[ruleAttribute] = priceRule.value
@@ -23,7 +23,7 @@ export const defaultAdminProductsVariantFields = [
"barcode",
"*prices",
"prices.price_rules.value",
"prices.price_rules.rule_type.rule_attribute",
"prices.price_rules.attribute",
"*options",
]
@@ -85,7 +85,7 @@ export const defaultAdminProductFields = [
"*variants",
"*variants.prices",
"variants.prices.price_rules.value",
"variants.prices.price_rules.rule_type.rule_attribute",
"variants.prices.price_rules.attribute",
"*variants.options",
"*sales_channels",
]
-2
View File
@@ -14,7 +14,6 @@ import { adminInviteRoutesMiddlewares } from "./admin/invites/middlewares"
import { adminOrderRoutesMiddlewares } from "./admin/orders/middlewares"
import { adminPaymentRoutesMiddlewares } from "./admin/payments/middlewares"
import { adminPriceListsRoutesMiddlewares } from "./admin/price-lists/middlewares"
import { adminPricingRoutesMiddlewares } from "./admin/pricing/middlewares"
import { adminProductCategoryRoutesMiddlewares } from "./admin/product-categories/middlewares"
import { adminProductTypeRoutesMiddlewares } from "./admin/product-types/middlewares"
import { adminProductTagRoutesMiddlewares } from "./admin/product-tags/middlewares"
@@ -81,7 +80,6 @@ export const config: MiddlewaresConfig = {
...adminPriceListsRoutesMiddlewares,
...adminInventoryRoutesMiddlewares,
...adminCollectionRoutesMiddlewares,
...adminPricingRoutesMiddlewares,
...adminShippingOptionRoutesMiddlewares,
...adminDraftOrderRoutesMiddlewares,
...adminSalesChannelRoutesMiddlewares,