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:
@@ -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 { adminPaymentRoutesMiddlewares } from "./admin/payments/middlewares"
|
||||
import { adminPriceListsRoutesMiddlewares } from "./admin/price-lists/middlewares"
|
||||
import { adminPricingRoutesMiddlewares } from "./admin/pricing/middlewares"
|
||||
import { adminProductRoutesMiddlewares } from "./admin/products/middlewares"
|
||||
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
||||
import { adminRegionRoutesMiddlewares } from "./admin/regions/middlewares"
|
||||
@@ -49,5 +50,6 @@ export const config: MiddlewaresConfig = {
|
||||
...adminPaymentRoutesMiddlewares,
|
||||
...adminPriceListsRoutesMiddlewares,
|
||||
...adminCollectionRoutesMiddlewares,
|
||||
...adminPricingRoutesMiddlewares,
|
||||
],
|
||||
}
|
||||
|
||||
@@ -116,8 +116,7 @@
|
||||
}
|
||||
],
|
||||
"checks": [],
|
||||
"foreignKeys": {
|
||||
}
|
||||
"foreignKeys": {}
|
||||
},
|
||||
{
|
||||
"columns": {
|
||||
@@ -520,6 +519,28 @@
|
||||
"nullable": false,
|
||||
"default": "0",
|
||||
"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",
|
||||
|
||||
@@ -24,8 +24,9 @@ export class Migration20230929122253 extends Migration {
|
||||
)
|
||||
|
||||
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(
|
||||
'create index "IDX_rule_type_rule_attribute" on "rule_type" ("rule_attribute");'
|
||||
)
|
||||
|
||||
@@ -6,9 +6,8 @@ import {
|
||||
Filter,
|
||||
Index,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
OneToOne,
|
||||
OnInit,
|
||||
OneToOne,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
@@ -30,7 +29,11 @@ class MoneyAmount {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
@Property({
|
||||
columnType: "text",
|
||||
nullable: true,
|
||||
index: "IDX_money_amount_currency_code",
|
||||
})
|
||||
currency_code: string | null
|
||||
|
||||
@ManyToMany({
|
||||
|
||||
@@ -32,6 +32,21 @@ class RuleType {
|
||||
@ManyToMany(() => PriceSet, (priceSet) => priceSet.rule_types)
|
||||
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()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "rul-typ")
|
||||
|
||||
@@ -19,6 +19,15 @@ export interface RuleTypeDTO {
|
||||
name: string
|
||||
rule_attribute: string
|
||||
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
|
||||
|
||||
@@ -2,7 +2,7 @@ import { BaseFilterable } from "../../dal"
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*
|
||||
*
|
||||
* A rule type's data.
|
||||
*/
|
||||
export interface RuleTypeDTO {
|
||||
@@ -15,20 +15,28 @@ export interface RuleTypeDTO {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
*
|
||||
*
|
||||
* The rule type to create.
|
||||
*/
|
||||
export interface CreateRuleTypeDTO {
|
||||
@@ -41,12 +49,12 @@ export interface CreateRuleTypeDTO {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
default_priority?: number
|
||||
@@ -54,7 +62,7 @@ export interface CreateRuleTypeDTO {
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*
|
||||
*
|
||||
* The data to update in a rule type. The `id` is used to identify which price set to update.
|
||||
*/
|
||||
export interface UpdateRuleTypeDTO {
|
||||
@@ -78,7 +86,7 @@ export interface UpdateRuleTypeDTO {
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*
|
||||
*
|
||||
* Filters to apply on rule types.
|
||||
*/
|
||||
export interface FilterableRuleTypeProps
|
||||
|
||||
Reference in New Issue
Block a user