feat(core-flows,medusa,pricing,types,utils): added price list workflows + endpoints (#6648)

Apologies for the giant PR in advance, but most of these are removing of files and migrations from old workflows and routes to new.

What:

- Adds CRUD endpoints for price lists
- Migrate workflows from old sdk to new
- Added missing updatePriceListPrices method to pricing module
This commit is contained in:
Riqwan Thamir
2024-03-15 11:09:02 +00:00
committed by GitHub
parent c3f26a6826
commit 9288f53327
81 changed files with 1959 additions and 2410 deletions
@@ -1,6 +1,3 @@
import { updatePriceLists } from "@medusajs/core-flows"
import { MedusaContainer } from "@medusajs/types"
import { MedusaV2Flag } from "@medusajs/utils"
import { Type } from "class-transformer"
import { IsArray, IsBoolean, IsOptional, ValidateNested } from "class-validator"
import { EntityManager } from "typeorm"
@@ -9,7 +6,6 @@ import { PriceList } from "../../../.."
import PriceListService from "../../../../services/price-list"
import { AdminPriceListPricesUpdateReq } from "../../../../types/price-list"
import { validator } from "../../../../utils/validator"
import { getPriceListPricingModule } from "./modules-queries"
/**
* @oas [post] /admin/price-lists/{id}/prices/batch
@@ -124,48 +120,22 @@ import { getPriceListPricingModule } from "./modules-queries"
*/
export default async (req, res) => {
const { id } = req.params
let priceList
const featureFlagRouter = req.scope.resolve("featureFlagRouter")
const manager: EntityManager = req.scope.resolve("manager")
const priceListService: PriceListService =
req.scope.resolve("priceListService")
const validated = await validator(AdminPostPriceListPricesPricesReq, req.body)
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const updatePriceListWorkflow = updatePriceLists(req.scope)
await manager.transaction(async (transactionManager) => {
await priceListService
.withTransaction(transactionManager)
.addPrices(id, validated.prices, validated.override)
})
const input = {
price_lists: [
{
id,
...validated,
},
],
}
await updatePriceListWorkflow.run({
input,
context: {
manager,
},
})
priceList = await getPriceListPricingModule(id, {
container: req.scope as MedusaContainer,
})
} else {
await manager.transaction(async (transactionManager) => {
await priceListService
.withTransaction(transactionManager)
.addPrices(id, validated.prices, validated.override)
})
priceList = await priceListService.retrieve(id, {
select: defaultAdminPriceListFields as (keyof PriceList)[],
relations: defaultAdminPriceListRelations,
})
}
const priceList = await priceListService.retrieve(id, {
select: defaultAdminPriceListFields as (keyof PriceList)[],
relations: defaultAdminPriceListRelations,
})
res.json({ price_list: priceList })
}
@@ -1,11 +1,4 @@
import { MedusaContainer, PricingTypes, WorkflowTypes } from "@medusajs/types"
import {
FlagRouter,
MedusaV2Flag,
PriceListStatus,
PriceListType,
} from "@medusajs/utils"
import { createPriceLists } from "@medusajs/core-flows"
import { PriceListStatus, PriceListType } from "@medusajs/utils"
import { Transform, Type } from "class-transformer"
import {
IsArray,
@@ -26,7 +19,6 @@ import {
CreatePriceListInput,
} from "../../../../types/price-list"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import { getPriceListPricingModule } from "./modules-queries"
import { transformOptionalDate } from "../../../../utils/validators/date-transform"
/**
@@ -155,57 +147,17 @@ export default async (req: Request, res) => {
req.scope.resolve("priceListService")
const manager: EntityManager = req.scope.resolve("manager")
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
let priceList
const isMedusaV2FlagEnabled = featureFlagRouter.isFeatureEnabled(
MedusaV2Flag.key
)
let priceList = await manager.transaction(async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.create(req.validatedBody as CreatePriceListInput)
})
if (isMedusaV2FlagEnabled) {
const createPriceListWorkflow = createPriceLists(req.scope)
const validatedInput = req.validatedBody as CreatePriceListInput
const rules: PricingTypes.CreatePriceListRules = {}
const customerGroups = validatedInput?.customer_groups || []
delete validatedInput.customer_groups
if (customerGroups.length) {
rules["customer_group_id"] = customerGroups.map((cg) => cg.id)
}
const input = {
price_lists: [
{
...validatedInput,
rules,
},
],
} as WorkflowTypes.PriceListWorkflow.CreatePriceListWorkflowInputDTO
const { result } = await createPriceListWorkflow.run({
input,
context: {
manager,
},
})
priceList = result[0]!.priceList
priceList = await getPriceListPricingModule(priceList.id, {
container: req.scope as MedusaContainer,
})
} else {
priceList = await manager.transaction(async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.create(req.validatedBody as CreatePriceListInput)
})
priceList = await priceListService.retrieve(priceList.id, {
select: defaultAdminPriceListFields as (keyof PriceList)[],
relations: defaultAdminPriceListRelations,
})
}
priceList = await priceListService.retrieve(priceList.id, {
select: defaultAdminPriceListFields as (keyof PriceList)[],
relations: defaultAdminPriceListRelations,
})
res.json({ price_list: priceList })
}
@@ -1,6 +1,3 @@
import { WorkflowTypes } from "@medusajs/types"
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { removePriceLists } from "@medusajs/core-flows"
import { EntityManager } from "typeorm"
import PriceListService from "../../../../services/price-list"
@@ -86,34 +83,13 @@ import PriceListService from "../../../../services/price-list"
*/
export default async (req, res) => {
const { id } = req.params
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
const manager: EntityManager = req.scope.resolve("manager")
const isMedusaV2FlagEnabled = featureFlagRouter.isFeatureEnabled(
MedusaV2Flag.key
)
if (isMedusaV2FlagEnabled) {
const removePriceListsWorkflow = removePriceLists(req.scope)
const input = {
price_lists: [id],
} as WorkflowTypes.PriceListWorkflow.RemovePriceListWorkflowInputDTO
await removePriceListsWorkflow.run({
input,
context: {
manager,
},
})
} else {
const priceListService: PriceListService =
req.scope.resolve("priceListService")
await manager.transaction(async (transactionManager) => {
await priceListService.withTransaction(transactionManager).delete(id)
})
}
const priceListService: PriceListService =
req.scope.resolve("priceListService")
await manager.transaction(async (transactionManager) => {
await priceListService.withTransaction(transactionManager).delete(id)
})
res.json({
id,
@@ -1,10 +1,7 @@
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { ArrayNotEmpty, IsString } from "class-validator"
import { EntityManager } from "typeorm"
import PriceListService from "../../../../services/price-list"
import { validator } from "../../../../utils/validator"
import { WorkflowTypes } from "@medusajs/types"
import { removePriceListPrices } from "@medusajs/core-flows"
/**
* @oas [delete] /admin/price-lists/{id}/prices/batch
@@ -101,43 +98,20 @@ import { removePriceListPrices } from "@medusajs/core-flows"
*/
export default async (req, res) => {
const { id } = req.params
const validated = await validator(
AdminDeletePriceListPricesPricesReq,
req.body
)
const manager: EntityManager = req.scope.resolve("manager")
const priceListService: PriceListService =
req.scope.resolve("priceListService")
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
const manager: EntityManager = req.scope.resolve("manager")
const isMedusaV2FlagEnabled = featureFlagRouter.isFeatureEnabled(
MedusaV2Flag.key
)
if (isMedusaV2FlagEnabled) {
const deletePriceListPricesWorkflow = removePriceListPrices(req.scope)
const input = {
price_list_id: id,
money_amount_ids: validated.price_ids,
} as WorkflowTypes.PriceListWorkflow.RemovePriceListPricesWorkflowInputDTO
await deletePriceListPricesWorkflow.run({
input,
context: {
manager,
},
})
} else {
await manager.transaction(async (transactionManager) => {
await priceListService
.withTransaction(transactionManager)
.deletePrices(id, validated.price_ids)
})
}
await manager.transaction(async (transactionManager) => {
await priceListService
.withTransaction(transactionManager)
.deletePrices(id, validated.price_ids)
})
res.json({ ids: validated.price_ids, object: "money-amount", deleted: true })
}
@@ -1,6 +1,3 @@
import { WorkflowTypes } from "@medusajs/types"
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { removePriceListProductPrices } from "@medusajs/core-flows"
import { EntityManager } from "typeorm"
import PriceListService from "../../../../services/price-list"
@@ -94,47 +91,18 @@ import PriceListService from "../../../../services/price-list"
*/
export default async (req, res) => {
const { id, product_id } = req.params
const priceListService: PriceListService =
req.scope.resolve("priceListService")
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
const manager: EntityManager = req.scope.resolve("manager")
const isMedusaV2FlagEnabled = featureFlagRouter.isFeatureEnabled(
MedusaV2Flag.key
)
let deletedPriceIds: string[] = []
if (isMedusaV2FlagEnabled) {
const deletePriceListProductsWorkflow = removePriceListProductPrices(
req.scope
)
const input = {
product_ids: [product_id],
price_list_id: id,
} as WorkflowTypes.PriceListWorkflow.RemovePriceListProductsWorkflowInputDTO
const { result } = await deletePriceListProductsWorkflow.run({
input,
context: {
manager,
},
})
deletedPriceIds = result
} else {
const [deletedIds] = await manager.transaction(
async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.deleteProductPrices(id, [product_id])
}
)
deletedPriceIds = deletedIds
}
const [deletedIds] = await manager.transaction(async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.deleteProductPrices(id, [product_id])
})
deletedPriceIds = deletedIds
return res.json({
ids: deletedPriceIds,
@@ -1,11 +1,8 @@
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { removePriceListProductPrices } from "@medusajs/core-flows"
import { ArrayNotEmpty, IsString } from "class-validator"
import { Request, Response } from "express"
import { EntityManager } from "typeorm"
import PriceListService from "../../../../services/price-list"
import { validator } from "../../../../utils/validator"
import { WorkflowTypes } from "@medusajs/types"
/**
* @oas [delete] /admin/price-lists/{id}/products/prices/batch
@@ -114,43 +111,16 @@ export default async (req: Request, res: Response) => {
const priceListService: PriceListService =
req.scope.resolve("priceListService")
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
const manager: EntityManager = req.scope.resolve("manager")
const isMedusaV2FlagEnabled = featureFlagRouter.isFeatureEnabled(
MedusaV2Flag.key
)
let deletedPriceIds: string[] = []
if (isMedusaV2FlagEnabled) {
const deletePriceListProductsWorkflow = removePriceListProductPrices(
req.scope
)
const [deletedIds] = await manager.transaction(async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.deleteProductPrices(id, validated.product_ids)
})
const input = {
product_ids: validated.product_ids,
price_list_id: id,
} as WorkflowTypes.PriceListWorkflow.RemovePriceListProductsWorkflowInputDTO
const { result } = await deletePriceListProductsWorkflow.run({
input,
context: {
manager,
},
})
deletedPriceIds = result
} else {
const [deletedIds] = await manager.transaction(
async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.deleteProductPrices(id, validated.product_ids)
}
)
deletedPriceIds = deletedIds
}
deletedPriceIds = deletedIds
return res.json({
ids: deletedPriceIds,
@@ -1,8 +1,5 @@
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { removePriceListVariantPrices } from "@medusajs/core-flows"
import { EntityManager } from "typeorm"
import PriceListService from "../../../../services/price-list"
import { WorkflowTypes } from "@medusajs/types"
/**
* @oas [delete] /admin/price-lists/{id}/variants/{variant_id}/prices
@@ -97,46 +94,16 @@ export default async (req, res) => {
const priceListService: PriceListService =
req.scope.resolve("priceListService")
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
const manager: EntityManager = req.scope.resolve("manager")
const isMedusaV2FlagEnabled = featureFlagRouter.isFeatureEnabled(
MedusaV2Flag.key
)
let deletedPriceIds: string[] = []
if (isMedusaV2FlagEnabled) {
const deletePriceListProductsWorkflow = removePriceListVariantPrices(
req.scope
)
const input = {
variant_ids: [variant_id],
price_list_id: id,
} as WorkflowTypes.PriceListWorkflow.RemovePriceListVariantsWorkflowInputDTO
const { result } = await deletePriceListProductsWorkflow.run({
input,
context: {
manager,
},
})
deletedPriceIds = result
} else {
const [deletedIds] = await manager.transaction(
async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.deleteVariantPrices(id, [variant_id])
}
)
deletedPriceIds = deletedIds
}
const [deletedIds] = await manager.transaction(async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.deleteVariantPrices(id, [variant_id])
})
return res.json({
ids: deletedPriceIds,
ids: deletedIds,
object: "money-amount",
deleted: true,
})
@@ -11,13 +11,12 @@ import {
extendedFindParamsMixin,
} from "../../../../types/common"
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import { Type } from "class-transformer"
import { Request } from "express"
import { ProductStatus } from "../../../../models"
import PriceListService from "../../../../services/price-list"
import { FilterableProductProps } from "../../../../types/product"
import { IsType, listProducts } from "../../../../utils"
import { IsType } from "../../../../utils"
/**
* @oas [get] /admin/price-lists/{id}/products
@@ -228,10 +227,6 @@ import { IsType, listProducts } from "../../../../utils"
export default async (req: Request, res) => {
const { id } = req.params
const { offset, limit } = req.validatedQuery
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
let products
let count
const priceListService: PriceListService =
req.scope.resolve("priceListService")
@@ -240,19 +235,11 @@ export default async (req: Request, res) => {
price_list_id: [id],
}
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
;[products, count] = await listProducts(
req.scope,
filterableFields,
req.listConfig
)
} else {
;[products, count] = await priceListService.listProducts(
id,
filterableFields,
req.listConfig
)
}
const [products, count] = await priceListService.listProducts(
id,
filterableFields,
req.listConfig
)
res.json({
products,
@@ -1,5 +1,4 @@
import { MedusaContainer, PricingTypes, WorkflowTypes } from "@medusajs/types"
import { MedusaV2Flag, PriceListStatus, PriceListType } from "@medusajs/utils"
import { PriceListStatus, PriceListType } from "@medusajs/utils"
import {
IsArray,
IsBoolean,
@@ -10,7 +9,6 @@ import {
} from "class-validator"
import { defaultAdminPriceListFields, defaultAdminPriceListRelations } from "."
import { updatePriceLists } from "@medusajs/core-flows"
import { Transform, Type } from "class-transformer"
import { EntityManager } from "typeorm"
import { PriceList } from "../../../.."
@@ -19,7 +17,6 @@ import PriceListService from "../../../../services/price-list"
import { AdminPriceListPricesUpdateReq } from "../../../../types/price-list"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import { validator } from "../../../../utils/validator"
import { getPriceListPricingModule } from "./modules-queries"
import { transformOptionalDate } from "../../../../utils/validators/date-transform"
/**
@@ -119,8 +116,6 @@ import { transformOptionalDate } from "../../../../utils/validators/date-transfo
*/
export default async (req, res) => {
const { id } = req.params
let priceList
const featureFlagRouter = req.scope.resolve("featureFlagRouter")
const manager: EntityManager = req.scope.resolve("manager")
const priceListService: PriceListService =
req.scope.resolve("priceListService")
@@ -130,48 +125,16 @@ export default async (req, res) => {
req.body
)
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const updateVariantsWorkflow = updatePriceLists(req.scope)
const customerGroups = validated.customer_groups
delete validated.customer_groups
await manager.transaction(async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.update(id, validated)
})
const updatePriceListInput = {
id,
...validated,
} as PricingTypes.UpdatePriceListDTO
if (Array.isArray(customerGroups)) {
updatePriceListInput.rules = {
customer_group_id: customerGroups.map((group) => group.id),
}
}
const input = {
price_lists: [updatePriceListInput],
} as WorkflowTypes.PriceListWorkflow.UpdatePriceListWorkflowInputDTO
await updateVariantsWorkflow.run({
input,
context: {
manager,
},
})
priceList = await getPriceListPricingModule(id, {
container: req.scope as MedusaContainer,
})
} else {
await manager.transaction(async (transactionManager) => {
return await priceListService
.withTransaction(transactionManager)
.update(id, validated)
})
priceList = await priceListService.retrieve(id, {
select: defaultAdminPriceListFields as (keyof PriceList)[],
relations: defaultAdminPriceListRelations,
})
}
const priceList = await priceListService.retrieve(id, {
select: defaultAdminPriceListFields as (keyof PriceList)[],
relations: defaultAdminPriceListRelations,
})
res.json({ price_list: priceList })
}