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
2024-07-01 09:47:03 +02:00
committed by GitHub
parent 1f360a3245
commit c661180c44
84 changed files with 661 additions and 3725 deletions
@@ -25,8 +25,6 @@ function buildPriceSet(
prices: StepInput[0]["prices"],
regionToCurrencyMap: Map<string, string>
): CreatePriceSetDTO {
const rules: CreatePriceSetDTO["rules"] = []
const shippingOptionPrices = prices.map((price) => {
if ("currency_code" in price) {
return {
@@ -35,10 +33,6 @@ function buildPriceSet(
}
}
rules.push({
rule_attribute: "region_id",
})
return {
currency_code: regionToCurrencyMap.get(price.region_id)!,
amount: price.amount,
@@ -48,7 +42,7 @@ function buildPriceSet(
}
})
return { rules, prices: shippingOptionPrices }
return { prices: shippingOptionPrices }
}
export const createShippingOptionsPriceSetsStepId =
@@ -1,4 +1,4 @@
import { CreateRuleTypeDTO, FulfillmentWorkflow } from "@medusajs/types"
import { FulfillmentWorkflow } from "@medusajs/types"
import {
createWorkflow,
transform,
@@ -9,7 +9,6 @@ import {
upsertShippingOptionsStep,
} from "../steps"
import { setShippingOptionsPriceSetsStep } from "../steps/set-shipping-options-price-sets"
import { createPricingRuleTypesStep } from "../../pricing"
export const createShippingOptionsWorkflowId =
"create-shipping-options-workflow"
@@ -45,18 +44,8 @@ export const createShippingOptionsWorkflow = createWorkflow(
shippingOptionsIndexToPrices: data.shippingOptionsIndexToPrices,
},
(data) => {
const ruleTypes = new Set<CreateRuleTypeDTO>()
const shippingOptionsPrices = data.shippingOptionsIndexToPrices.map(
({ shipping_option_index, prices }) => {
prices.forEach((price) => {
if ("region_id" in price) {
ruleTypes.add({
name: "region_id",
rule_attribute: "region_id",
})
}
})
return {
id: data.shippingOptions[shipping_option_index].id,
prices,
@@ -66,13 +55,10 @@ export const createShippingOptionsWorkflow = createWorkflow(
return {
shippingOptionsPrices,
ruleTypes: Array.from(ruleTypes) as CreateRuleTypeDTO[],
}
}
)
createPricingRuleTypesStep(normalizedShippingOptionsPrices.ruleTypes)
const shippingOptionsPriceSetsLinkData = createShippingOptionsPriceSetsStep(
normalizedShippingOptionsPrices.shippingOptionsPrices
)
@@ -1,8 +1,4 @@
import {
CreateRuleTypeDTO,
FulfillmentWorkflow,
RuleTypeDTO,
} from "@medusajs/types"
import { FulfillmentWorkflow } from "@medusajs/types"
import {
createWorkflow,
transform,
@@ -12,7 +8,6 @@ import {
setShippingOptionsPricesStep,
upsertShippingOptionsStep,
} from "../steps"
import { createPricingRuleTypesStep } from "../../pricing"
export const updateShippingOptionsWorkflowId =
"update-shipping-options-workflow"
@@ -49,18 +44,8 @@ export const updateShippingOptionsWorkflow = createWorkflow(
shippingOptionsIndexToPrices: data.shippingOptionsIndexToPrices,
},
(data) => {
const ruleTypes = new Set<Partial<RuleTypeDTO>>()
const shippingOptionsPrices = data.shippingOptionsIndexToPrices.map(
({ shipping_option_index, prices }) => {
prices?.forEach((price) => {
if ("region_id" in price) {
ruleTypes.add({
name: "region_id",
rule_attribute: "region_id",
})
}
})
return {
id: data.shippingOptions[shipping_option_index].id,
prices,
@@ -70,13 +55,10 @@ export const updateShippingOptionsWorkflow = createWorkflow(
return {
shippingOptionsPrices,
ruleTypes: Array.from(ruleTypes) as CreateRuleTypeDTO[],
}
}
)
createPricingRuleTypesStep(normalizedShippingOptionsPrices.ruleTypes)
setShippingOptionsPricesStep(
normalizedShippingOptionsPrices.shippingOptionsPrices
)
@@ -44,7 +44,7 @@ export const updatePriceListsStep = createStep(
await pricingModule.updatePriceLists(
dataBeforeUpdate.map((data) => {
const { price_list_rules: priceListRules = [], rules, ...rest } = data
const { price_list_rules: priceListRules = [], ...rest } = data
const updateData: UpdatePriceListDTO = {
...rest,
@@ -82,14 +82,8 @@ async function getDataBeforeUpdate(
selectsClone.splice(index, 1)
}
selectsClone.push(
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute"
)
relationsClone.push(
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type"
)
selectsClone.push("price_list_rules.value", "price_list_rules.attribute")
relationsClone.push("price_list_rules")
}
const dataBeforeUpdate = await pricingModule.listPriceLists(
@@ -1,2 +1 @@
export * from "./steps"
export * from "./workflows"
@@ -1,47 +0,0 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { CreateRuleTypeDTO, IPricingModuleService } from "@medusajs/types"
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
export const createPricingRuleTypesStepId = "create-pricing-rule-types"
export const createPricingRuleTypesStep = createStep(
createPricingRuleTypesStepId,
async (data: CreateRuleTypeDTO[], { container }) => {
if (!data?.length) {
return
}
const pricingModule = container.resolve<IPricingModuleService>(
ModuleRegistrationName.PRICING
)
const existingRuleTypes = await pricingModule.listRuleTypes({
rule_attribute: data.map((d) => d.rule_attribute),
})
const existingRuleTypeAttributes = new Set(
existingRuleTypes.map((ruleType) => ruleType.rule_attribute)
)
const ruleTypesToCreate = data.filter(
(dataItem) => !existingRuleTypeAttributes.has(dataItem.rule_attribute)
)
const ruleTypes = await pricingModule.createRuleTypes(ruleTypesToCreate)
return new StepResponse(
ruleTypes,
ruleTypes.map((ruleType) => ruleType.id)
)
},
async (ruleTypeIds, { container }) => {
if (!ruleTypeIds?.length) {
return
}
const pricingModule = container.resolve<IPricingModuleService>(
ModuleRegistrationName.PRICING
)
await pricingModule.deleteRuleTypes(ruleTypeIds)
}
)
@@ -1,31 +0,0 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IPricingModuleService } from "@medusajs/types"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
export const deletePricingRuleTypesStepId = "delete-pricing-rule-types"
export const deletePricingRuleTypesStep = createStep(
deletePricingRuleTypesStepId,
async (ids: string[], { container }) => {
const pricingModule = container.resolve<IPricingModuleService>(
ModuleRegistrationName.PRICING
)
// TODO: implement soft deleting rule types
// await pricingModule.softDeleteRuleTypes(ids)
await pricingModule.deleteRuleTypes(ids)
return new StepResponse(void 0, ids)
},
async (ids, { container }) => {
if (!ids?.length) {
return
}
const pricingModule = container.resolve<IPricingModuleService>(
ModuleRegistrationName.PRICING
)
// TODO: implement restoring soft deleted rule types
// await pricingModule.restoreRuleTypes(ids)
}
)
@@ -1,5 +1,2 @@
export * from "./create-price-sets"
export * from "./update-price-sets"
export * from "./create-pricing-rule-types"
export * from "./delete-pricing-rule-types"
export * from "./update-pricing-rule-types"
@@ -1,48 +0,0 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IPricingModuleService, UpdateRuleTypeDTO } from "@medusajs/types"
import {
convertItemResponseToUpdateRequest,
getSelectsAndRelationsFromObjectArray,
} from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
export const updatePricingRuleTypesStepId = "update-pricing-rule-types"
export const updatePricingRuleTypesStep = createStep(
updatePricingRuleTypesStepId,
async (data: UpdateRuleTypeDTO[], { container }) => {
const pricingModule = container.resolve<IPricingModuleService>(
ModuleRegistrationName.PRICING
)
const { selects, relations } = getSelectsAndRelationsFromObjectArray(data)
const dataBeforeUpdate = await pricingModule.listRuleTypes(
{ id: data.map((d) => d.id) },
{ relations, select: selects }
)
const updatedRuleTypes = await pricingModule.updateRuleTypes(data)
return new StepResponse(updatedRuleTypes, {
dataBeforeUpdate,
selects,
relations,
})
},
async (revertInput, { container }) => {
if (!revertInput) {
return
}
const { dataBeforeUpdate = [], selects, relations } = revertInput
const pricingModule = container.resolve<IPricingModuleService>(
ModuleRegistrationName.PRICING
)
await pricingModule.updateRuleTypes(
dataBeforeUpdate.map((data) =>
convertItemResponseToUpdateRequest(data, selects, relations)
)
)
}
)
@@ -1,13 +0,0 @@
import { CreateRuleTypeDTO, RuleTypeDTO } from "@medusajs/types"
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { createPricingRuleTypesStep } from "../steps"
type WorkflowInput = { data: CreateRuleTypeDTO[] }
export const createPricingRuleTypesWorkflowId = "create-pricing-rule-types"
export const createPricingRuleTypesWorkflow = createWorkflow(
createPricingRuleTypesWorkflowId,
(input: WorkflowData<WorkflowInput>): WorkflowData<RuleTypeDTO[]> => {
return createPricingRuleTypesStep(input.data)
}
)
@@ -1,12 +0,0 @@
import { createWorkflow, WorkflowData } from "@medusajs/workflows-sdk"
import { deletePricingRuleTypesStep } from "../steps"
type WorkflowInput = { ids: string[] }
export const deletePricingRuleTypesWorkflowId = "delete-pricing-rule-types"
export const deletePricingRuleTypesWorkflow = createWorkflow(
deletePricingRuleTypesWorkflowId,
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
deletePricingRuleTypesStep(input.ids)
}
)
@@ -1,3 +0,0 @@
export * from "./create-pricing-rule-types"
export * from "./delete-pricing-rule-types"
export * from "./update-pricing-rule-types"
@@ -1,13 +0,0 @@
import { RuleTypeDTO, UpdateRuleTypeDTO } from "@medusajs/types"
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { updatePricingRuleTypesStep } from "../steps"
type WorkflowInput = { data: UpdateRuleTypeDTO[] }
export const updatePricingRuleTypesWorkflowId = "update-pricing-rule-types"
export const updatePricingRuleTypesWorkflow = createWorkflow(
updatePricingRuleTypesWorkflowId,
(input: WorkflowData<WorkflowInput>): WorkflowData<RuleTypeDTO[]> => {
return updatePricingRuleTypesStep(input.data)
}
)