feat(medusa,pricing,types): added get endpoints for pricing rule types (#6678)
what: - adds list endpoint for rule types - adds get endpoint for rule types
This commit is contained in:
1 parent
f0c8142635
commit
d4b921f3db
14 files changed
+312
-14
No files matched your search
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/pricing": patch
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(medusa,pricing,types): added get endpoints for pricing rule types
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IPricingModuleService, RuleTypeDTO } from "@medusajs/types"
|
||||||
|
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||||
|
import { createAdminUser } from "../../../../helpers/create-admin-user"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = { headers: { "x-medusa-access-token": "test_token" } }
|
||||||
|
|
||||||
|
medusaIntegrationTestRunner({
|
||||||
|
env,
|
||||||
|
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||||
|
describe("Admin: Pricing Rule Types API", () => {
|
||||||
|
let appContainer
|
||||||
|
let pricingModule: IPricingModuleService
|
||||||
|
let ruleTypes: RuleTypeDTO[]
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
appContainer = getContainer()
|
||||||
|
pricingModule = appContainer.resolve(ModuleRegistrationName.PRICING)
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
||||||
|
|
||||||
|
ruleTypes = await pricingModule.createRuleTypes([
|
||||||
|
{ name: "Customer Group ID", rule_attribute: "customer_group_id" },
|
||||||
|
{ name: "Region ID", rule_attribute: "region_id" },
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("GET /admin/pricing", () => {
|
||||||
|
it("should get all rule types and its prices with rules", async () => {
|
||||||
|
let response = await api.get(
|
||||||
|
`/admin/pricing/rule-types`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.count).toEqual(2)
|
||||||
|
expect(response.data.rule_types).toEqual([
|
||||||
|
expect.objectContaining({ id: expect.any(String) }),
|
||||||
|
expect.objectContaining({ id: expect.any(String) }),
|
||||||
|
])
|
||||||
|
|
||||||
|
response = await api.get(
|
||||||
|
`/admin/pricing/rule-types?fields=id,rule_attribute,created_at`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.count).toEqual(2)
|
||||||
|
expect(response.data.rule_types).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
{
|
||||||
|
id: ruleTypes[0].id,
|
||||||
|
rule_attribute: ruleTypes[0].rule_attribute,
|
||||||
|
created_at: expect.any(String),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: ruleTypes[1].id,
|
||||||
|
rule_attribute: ruleTypes[1].rule_attribute,
|
||||||
|
created_at: expect.any(String),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("GET /admin/pricing/:id", () => {
|
||||||
|
it("should retrieve a rule type and its prices with rules", async () => {
|
||||||
|
const ruleType = ruleTypes[0]
|
||||||
|
|
||||||
|
let response = await api.get(
|
||||||
|
`/admin/pricing/rule-types/${ruleType.id}`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.rule_type).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: ruleType.id,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await api.get(
|
||||||
|
`/admin/pricing/rule-types/${ruleType.id}?fields=id,created_at`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.data.rule_type).toEqual({
|
||||||
|
id: ruleType.id,
|
||||||
|
created_at: expect.any(String),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should throw an error when rule type is not found", async () => {
|
||||||
|
const error = await api
|
||||||
|
.get(`/admin/pricing/rule-types/does-not-exist`, adminHeaders)
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(error.response.status).toBe(404)
|
||||||
|
expect(error.response.data).toEqual({
|
||||||
|
type: "not_found",
|
||||||
|
message: "RuleType with id: does-not-exist was not found",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { transformQuery } from "../../../api/middlewares"
|
||||||
|
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||||
|
import { authenticate } from "../../../utils/authenticate-middleware"
|
||||||
|
import * as QueryConfig from "./query-config"
|
||||||
|
import {
|
||||||
|
AdminGetPricingRuleTypesParams,
|
||||||
|
AdminGetPricingRuleTypesRuleTypeParams,
|
||||||
|
} from "./validators"
|
||||||
|
|
||||||
|
export const adminPricingRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
|
{
|
||||||
|
matcher: "/admin/pricing*",
|
||||||
|
middlewares: [authenticate("admin", ["bearer", "session"])],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/pricing/rule-types",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetPricingRuleTypesParams,
|
||||||
|
QueryConfig.listTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/pricing/rule-types/:id",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetPricingRuleTypesRuleTypeParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
export const defaultAdminPricingRuleTypeRelations = []
|
||||||
|
export const allowedAdminPricingRuleTypeRelations = []
|
||||||
|
export const defaultAdminPricingRuleTypeFields = [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"rule_attribute",
|
||||||
|
"default_priority",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const retrieveTransformQueryConfig = {
|
||||||
|
defaultFields: defaultAdminPricingRuleTypeFields,
|
||||||
|
defaultRelations: defaultAdminPricingRuleTypeRelations,
|
||||||
|
allowedRelations: allowedAdminPricingRuleTypeRelations,
|
||||||
|
isList: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const listTransformQueryConfig = {
|
||||||
|
...retrieveTransformQueryConfig,
|
||||||
|
isList: true,
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IPricingModuleService } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
AuthenticatedMedusaRequest,
|
||||||
|
MedusaResponse,
|
||||||
|
} from "../../../../../types/routing"
|
||||||
|
import { AdminGetPricingRuleTypesRuleTypeParams } from "../../validators"
|
||||||
|
|
||||||
|
export const GET = async (
|
||||||
|
req: AuthenticatedMedusaRequest<AdminGetPricingRuleTypesRuleTypeParams>,
|
||||||
|
res: MedusaResponse
|
||||||
|
) => {
|
||||||
|
const pricingModule: IPricingModuleService = req.scope.resolve(
|
||||||
|
ModuleRegistrationName.PRICING
|
||||||
|
)
|
||||||
|
|
||||||
|
const ruleType = await pricingModule.retrieveRuleType(req.params.id, {
|
||||||
|
select: req.retrieveConfig.select,
|
||||||
|
relations: req.retrieveConfig.relations,
|
||||||
|
})
|
||||||
|
|
||||||
|
res.status(200).json({ rule_type: ruleType })
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IPricingModuleService } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
AuthenticatedMedusaRequest,
|
||||||
|
MedusaResponse,
|
||||||
|
} from "../../../../types/routing"
|
||||||
|
import { AdminGetPricingRuleTypesParams } from "../validators"
|
||||||
|
|
||||||
|
export const GET = async (
|
||||||
|
req: AuthenticatedMedusaRequest<AdminGetPricingRuleTypesParams>,
|
||||||
|
res: MedusaResponse
|
||||||
|
) => {
|
||||||
|
const pricingModule: IPricingModuleService = req.scope.resolve(
|
||||||
|
ModuleRegistrationName.PRICING
|
||||||
|
)
|
||||||
|
|
||||||
|
const [ruleTypes, count] = await pricingModule.listAndCountRuleTypes(
|
||||||
|
req.filterableFields,
|
||||||
|
req.listConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
const { limit, offset } = req.validatedQuery
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
count,
|
||||||
|
rule_types: ruleTypes,
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { IsOptional, IsString } from "class-validator"
|
||||||
|
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
||||||
|
|
||||||
|
export class AdminGetPricingRuleTypesRuleTypeParams extends FindParams {}
|
||||||
|
export class AdminGetPricingRuleTypesParams extends extendedFindParamsMixin({
|
||||||
|
limit: 100,
|
||||||
|
offset: 0,
|
||||||
|
}) {
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
rule_attribute?: string[]
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares"
|
|||||||
import { adminInviteRoutesMiddlewares } from "./admin/invites/middlewares"
|
import { adminInviteRoutesMiddlewares } from "./admin/invites/middlewares"
|
||||||
import { adminPaymentRoutesMiddlewares } from "./admin/payments/middlewares"
|
import { adminPaymentRoutesMiddlewares } from "./admin/payments/middlewares"
|
||||||
import { adminPriceListsRoutesMiddlewares } from "./admin/price-lists/middlewares"
|
import { adminPriceListsRoutesMiddlewares } from "./admin/price-lists/middlewares"
|
||||||
|
import { adminPricingRoutesMiddlewares } from "./admin/pricing/middlewares"
|
||||||
import { adminProductRoutesMiddlewares } from "./admin/products/middlewares"
|
import { adminProductRoutesMiddlewares } from "./admin/products/middlewares"
|
||||||
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
||||||
import { adminRegionRoutesMiddlewares } from "./admin/regions/middlewares"
|
import { adminRegionRoutesMiddlewares } from "./admin/regions/middlewares"
|
||||||
@@ -49,5 +50,6 @@ export const config: MiddlewaresConfig = {
|
|||||||
...adminPaymentRoutesMiddlewares,
|
...adminPaymentRoutesMiddlewares,
|
||||||
...adminPriceListsRoutesMiddlewares,
|
...adminPriceListsRoutesMiddlewares,
|
||||||
...adminCollectionRoutesMiddlewares,
|
...adminCollectionRoutesMiddlewares,
|
||||||
|
...adminPricingRoutesMiddlewares,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@@ -116,8 +116,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"checks": [],
|
"checks": [],
|
||||||
"foreignKeys": {
|
"foreignKeys": {}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": {
|
"columns": {
|
||||||
@@ -520,6 +519,28 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"mappedType": "integer"
|
"mappedType": "integer"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "rule_type",
|
"name": "rule_type",
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ export class Migration20230929122253 extends Migration {
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'create table "rule_type" ("id" text not null, "name" text not null, "rule_attribute" text not null, "default_priority" integer not null default 0, constraint "rule_type_pkey" primary key ("id"));'
|
'create table "rule_type" ("id" text not null, "name" text not null, "rule_attribute" text not null, "default_priority" integer not null default 0, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), constraint "rule_type_pkey" primary key ("id"));'
|
||||||
)
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'create index "IDX_rule_type_rule_attribute" on "rule_type" ("rule_attribute");'
|
'create index "IDX_rule_type_rule_attribute" on "rule_type" ("rule_attribute");'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ import {
|
|||||||
Filter,
|
Filter,
|
||||||
Index,
|
Index,
|
||||||
ManyToMany,
|
ManyToMany,
|
||||||
ManyToOne,
|
|
||||||
OneToOne,
|
|
||||||
OnInit,
|
OnInit,
|
||||||
|
OneToOne,
|
||||||
OptionalProps,
|
OptionalProps,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
Property,
|
Property,
|
||||||
@@ -30,7 +29,11 @@ class MoneyAmount {
|
|||||||
@PrimaryKey({ columnType: "text" })
|
@PrimaryKey({ columnType: "text" })
|
||||||
id!: string
|
id!: string
|
||||||
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
@Property({
|
||||||
|
columnType: "text",
|
||||||
|
nullable: true,
|
||||||
|
index: "IDX_money_amount_currency_code",
|
||||||
|
})
|
||||||
currency_code: string | null
|
currency_code: string | null
|
||||||
|
|
||||||
@ManyToMany({
|
@ManyToMany({
|
||||||
|
|||||||
@@ -32,6 +32,21 @@ class RuleType {
|
|||||||
@ManyToMany(() => PriceSet, (priceSet) => priceSet.rule_types)
|
@ManyToMany(() => PriceSet, (priceSet) => priceSet.rule_types)
|
||||||
price_sets = new Collection<PriceSet>(this)
|
price_sets = new Collection<PriceSet>(this)
|
||||||
|
|
||||||
|
@Property({
|
||||||
|
onCreate: () => new Date(),
|
||||||
|
columnType: "timestamptz",
|
||||||
|
defaultRaw: "now()",
|
||||||
|
})
|
||||||
|
created_at: Date
|
||||||
|
|
||||||
|
@Property({
|
||||||
|
onCreate: () => new Date(),
|
||||||
|
onUpdate: () => new Date(),
|
||||||
|
columnType: "timestamptz",
|
||||||
|
defaultRaw: "now()",
|
||||||
|
})
|
||||||
|
updated_at: Date
|
||||||
|
|
||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
onCreate() {
|
onCreate() {
|
||||||
this.id = generateEntityId(this.id, "rul-typ")
|
this.id = generateEntityId(this.id, "rul-typ")
|
||||||
|
|||||||
@@ -19,6 +19,15 @@ export interface RuleTypeDTO {
|
|||||||
name: string
|
name: string
|
||||||
rule_attribute: string
|
rule_attribute: string
|
||||||
default_priority: number
|
default_priority: number
|
||||||
|
/**
|
||||||
|
* The creation date of the rule type.
|
||||||
|
*/
|
||||||
|
created_at?: Date | string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The update date of the rule type.
|
||||||
|
*/
|
||||||
|
updated_at?: Date | string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FilterableRuleTypeProps
|
export interface FilterableRuleTypeProps
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { BaseFilterable } from "../../dal"
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface
|
* @interface
|
||||||
*
|
*
|
||||||
* A rule type's data.
|
* A rule type's data.
|
||||||
*/
|
*/
|
||||||
export interface RuleTypeDTO {
|
export interface RuleTypeDTO {
|
||||||
@@ -15,20 +15,28 @@ export interface RuleTypeDTO {
|
|||||||
*/
|
*/
|
||||||
name: string
|
name: string
|
||||||
/**
|
/**
|
||||||
* The unique name used to later identify the rule_attribute. For example, it can be used in the `context` parameter of
|
* The unique name used to later identify the rule_attribute. For example, it can be used in the `context` parameter of
|
||||||
* the `calculatePrices` method to specify a rule for calculating the price.
|
* the `calculatePrices` method to specify a rule for calculating the price.
|
||||||
*/
|
*/
|
||||||
rule_attribute: string
|
rule_attribute: string
|
||||||
/**
|
/**
|
||||||
* The priority of the rule type. This is useful when calculating the price of a price set, and multiple rules satisfy
|
* The priority of the rule type. This is useful when calculating the price of a price set, and multiple rules satisfy
|
||||||
* the provided context. The higher the value, the higher the priority of the rule type.
|
* the provided context. The higher the value, the higher the priority of the rule type.
|
||||||
*/
|
*/
|
||||||
default_priority: number
|
default_priority: number
|
||||||
|
/**
|
||||||
|
* The creation date of the rule type.
|
||||||
|
*/
|
||||||
|
created_at?: Date | string
|
||||||
|
/**
|
||||||
|
* The update date of the rule type.
|
||||||
|
*/
|
||||||
|
updated_at?: Date | string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface
|
* @interface
|
||||||
*
|
*
|
||||||
* The rule type to create.
|
* The rule type to create.
|
||||||
*/
|
*/
|
||||||
export interface CreateRuleTypeDTO {
|
export interface CreateRuleTypeDTO {
|
||||||
@@ -41,12 +49,12 @@ export interface CreateRuleTypeDTO {
|
|||||||
*/
|
*/
|
||||||
name: string
|
name: string
|
||||||
/**
|
/**
|
||||||
* The unique name used to later identify the rule_attribute. For example, it can be used in the `context` parameter of the `calculatePrices`
|
* The unique name used to later identify the rule_attribute. For example, it can be used in the `context` parameter of the `calculatePrices`
|
||||||
* method to specify a rule for calculating the price.
|
* method to specify a rule for calculating the price.
|
||||||
*/
|
*/
|
||||||
rule_attribute: string
|
rule_attribute: string
|
||||||
/**
|
/**
|
||||||
* The priority of the rule type. This is useful when calculating the price of a price set, and multiple rules satisfy the provided context.
|
* The priority of the rule type. This is useful when calculating the price of a price set, and multiple rules satisfy the provided context.
|
||||||
* The higher the value, the higher the priority of the rule type.
|
* The higher the value, the higher the priority of the rule type.
|
||||||
*/
|
*/
|
||||||
default_priority?: number
|
default_priority?: number
|
||||||
@@ -54,7 +62,7 @@ export interface CreateRuleTypeDTO {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface
|
* @interface
|
||||||
*
|
*
|
||||||
* The data to update in a rule type. The `id` is used to identify which price set to update.
|
* The data to update in a rule type. The `id` is used to identify which price set to update.
|
||||||
*/
|
*/
|
||||||
export interface UpdateRuleTypeDTO {
|
export interface UpdateRuleTypeDTO {
|
||||||
@@ -78,7 +86,7 @@ export interface UpdateRuleTypeDTO {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface
|
* @interface
|
||||||
*
|
*
|
||||||
* Filters to apply on rule types.
|
* Filters to apply on rule types.
|
||||||
*/
|
*/
|
||||||
export interface FilterableRuleTypeProps
|
export interface FilterableRuleTypeProps
|
||||||
|
|||||||
Reference in new issue
Block a user