feat(medusa,types): add promotion list/get endpoint (#6110)
what: - adds get promotion endpoint (RESOLVES CORE-1677) - adds list promotions endpoint (RESOLVES CORE-1676) - uses new API routes
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(medusa,types): add promotion list and get endpoint
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IPromotionModuleService } from "@medusajs/types"
|
||||||
|
import { PromotionType } from "@medusajs/utils"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
import adminSeeder from "../../../../helpers/admin-seeder"
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GET /admin/promotions", () => {
|
||||||
|
let dbConnection
|
||||||
|
let appContainer
|
||||||
|
let shutdownServer
|
||||||
|
let promotionModuleService: IPromotionModuleService
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
appContainer = getContainer()
|
||||||
|
promotionModuleService = appContainer.resolve(
|
||||||
|
ModuleRegistrationName.PROMOTION
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get all promotions and its count", async () => {
|
||||||
|
await promotionModuleService.create([
|
||||||
|
{
|
||||||
|
code: "TEST",
|
||||||
|
type: PromotionType.STANDARD,
|
||||||
|
application_method: {
|
||||||
|
type: "fixed",
|
||||||
|
target_type: "order",
|
||||||
|
value: "100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(`/admin/promotions`, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.count).toEqual(1)
|
||||||
|
expect(response.data.promotions).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
code: "TEST",
|
||||||
|
campaign: null,
|
||||||
|
is_automatic: false,
|
||||||
|
type: "standard",
|
||||||
|
created_at: expect.any(String),
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
deleted_at: null,
|
||||||
|
application_method: expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
value: 100,
|
||||||
|
type: "fixed",
|
||||||
|
target_type: "order",
|
||||||
|
allocation: null,
|
||||||
|
created_at: expect.any(String),
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
deleted_at: null,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get all promotions and its count filtered", async () => {
|
||||||
|
const [createdPromotion] = await promotionModuleService.create([
|
||||||
|
{
|
||||||
|
code: "TEST",
|
||||||
|
type: PromotionType.STANDARD,
|
||||||
|
application_method: {
|
||||||
|
type: "fixed",
|
||||||
|
target_type: "order",
|
||||||
|
value: "100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(
|
||||||
|
`/admin/promotions?fields=code,created_at,application_method.id`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.count).toEqual(1)
|
||||||
|
expect(response.data.promotions).toEqual([
|
||||||
|
{
|
||||||
|
id: expect.any(String),
|
||||||
|
code: "TEST",
|
||||||
|
created_at: expect.any(String),
|
||||||
|
application_method: {
|
||||||
|
id: expect.any(String),
|
||||||
|
promotion: expect.any(Object),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IPromotionModuleService } from "@medusajs/types"
|
||||||
|
import { PromotionType } from "@medusajs/utils"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
import adminSeeder from "../../../../helpers/admin-seeder"
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GET /admin/promotions", () => {
|
||||||
|
let dbConnection
|
||||||
|
let appContainer
|
||||||
|
let shutdownServer
|
||||||
|
let promotionModuleService: IPromotionModuleService
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
appContainer = getContainer()
|
||||||
|
promotionModuleService = appContainer.resolve(
|
||||||
|
ModuleRegistrationName.PROMOTION
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should throw an error if id does not exist", async () => {
|
||||||
|
const api = useApi() as any
|
||||||
|
const { response } = await api
|
||||||
|
.get(`/admin/promotions/does-not-exist`, adminHeaders)
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(404)
|
||||||
|
expect(response.data.message).toEqual(
|
||||||
|
"Promotion with id: does-not-exist was not found"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get the requested promotion", async () => {
|
||||||
|
const createdPromotion = await promotionModuleService.create({
|
||||||
|
code: "TEST",
|
||||||
|
type: PromotionType.STANDARD,
|
||||||
|
application_method: {
|
||||||
|
type: "fixed",
|
||||||
|
target_type: "order",
|
||||||
|
value: "100",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(
|
||||||
|
`/admin/promotions/${createdPromotion.id}`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.promotion).toEqual({
|
||||||
|
id: expect.any(String),
|
||||||
|
code: "TEST",
|
||||||
|
campaign: null,
|
||||||
|
is_automatic: false,
|
||||||
|
type: "standard",
|
||||||
|
created_at: expect.any(String),
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
deleted_at: null,
|
||||||
|
application_method: {
|
||||||
|
id: expect.any(String),
|
||||||
|
promotion: expect.any(Object),
|
||||||
|
value: 100,
|
||||||
|
type: "fixed",
|
||||||
|
target_type: "order",
|
||||||
|
max_quantity: 0,
|
||||||
|
allocation: null,
|
||||||
|
created_at: expect.any(String),
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
deleted_at: null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get the requested promotion with filtered fields and relations", async () => {
|
||||||
|
const createdPromotion = await promotionModuleService.create({
|
||||||
|
code: "TEST",
|
||||||
|
type: PromotionType.STANDARD,
|
||||||
|
application_method: {
|
||||||
|
type: "fixed",
|
||||||
|
target_type: "order",
|
||||||
|
value: "100",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(
|
||||||
|
`/admin/promotions/${createdPromotion.id}?fields=id,code&expand=`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.promotion).toEqual({
|
||||||
|
id: expect.any(String),
|
||||||
|
code: "TEST",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -66,5 +66,10 @@ module.exports = {
|
|||||||
resources: "shared",
|
resources: "shared",
|
||||||
resolve: "@medusajs/pricing",
|
resolve: "@medusajs/pricing",
|
||||||
},
|
},
|
||||||
|
[Modules.PROMOTION]: {
|
||||||
|
scope: "internal",
|
||||||
|
resources: "shared",
|
||||||
|
resolve: "@medusajs/promotion",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
"@medusajs/modules-sdk": "workspace:^",
|
"@medusajs/modules-sdk": "workspace:^",
|
||||||
"@medusajs/pricing": "workspace:^",
|
"@medusajs/pricing": "workspace:^",
|
||||||
"@medusajs/product": "workspace:^",
|
"@medusajs/product": "workspace:^",
|
||||||
|
"@medusajs/promotion": "workspace:^",
|
||||||
|
"@medusajs/utils": "workspace:^",
|
||||||
"faker": "^5.5.3",
|
"faker": "^5.5.3",
|
||||||
"medusa-fulfillment-webshipper": "workspace:*",
|
"medusa-fulfillment-webshipper": "workspace:*",
|
||||||
"medusa-interfaces": "workspace:*",
|
"medusa-interfaces": "workspace:*",
|
||||||
@@ -27,6 +29,7 @@
|
|||||||
"@babel/cli": "^7.12.10",
|
"@babel/cli": "^7.12.10",
|
||||||
"@babel/core": "^7.12.10",
|
"@babel/core": "^7.12.10",
|
||||||
"@babel/node": "^7.12.10",
|
"@babel/node": "^7.12.10",
|
||||||
|
"@medusajs/types": "workspace:^",
|
||||||
"babel-preset-medusa-package": "*",
|
"babel-preset-medusa-package": "*",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"jest-environment-node": "26.6.2"
|
"jest-environment-node": "26.6.2"
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IPromotionModuleService } from "@medusajs/types"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||||
|
|
||||||
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const promotionModuleService: IPromotionModuleService = req.scope.resolve(
|
||||||
|
ModuleRegistrationName.PROMOTION
|
||||||
|
)
|
||||||
|
|
||||||
|
const promotion = await promotionModuleService.retrieve(req.params.id, {
|
||||||
|
select: req.retrieveConfig.select,
|
||||||
|
relations: req.retrieveConfig.relations,
|
||||||
|
})
|
||||||
|
|
||||||
|
res.status(200).json({ promotion })
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { MedusaV2Flag } from "@medusajs/utils"
|
||||||
|
import { isFeatureFlagEnabled, transformQuery } from "../../../api/middlewares"
|
||||||
|
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||||
|
import * as QueryConfig from "./query-config"
|
||||||
|
import {
|
||||||
|
AdminGetPromotionsParams,
|
||||||
|
AdminGetPromotionsPromotionParams,
|
||||||
|
} from "./validators"
|
||||||
|
|
||||||
|
export const adminPromotionRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
|
{
|
||||||
|
matcher: "/admin/promotions*",
|
||||||
|
middlewares: [isFeatureFlagEnabled(MedusaV2Flag.key)],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/promotions",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetPromotionsParams,
|
||||||
|
QueryConfig.listTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/promotions/:id",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetPromotionsPromotionParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
export const defaultAdminPromotionRelations = ["campaign", "application_method"]
|
||||||
|
export const allowedAdminPromotionRelations = [
|
||||||
|
...defaultAdminPromotionRelations,
|
||||||
|
]
|
||||||
|
export const defaultAdminPromotionFields = [
|
||||||
|
"id",
|
||||||
|
"code",
|
||||||
|
"campaign",
|
||||||
|
"is_automatic",
|
||||||
|
"type",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const retrieveTransformQueryConfig = {
|
||||||
|
defaultFields: defaultAdminPromotionFields,
|
||||||
|
defaultRelations: defaultAdminPromotionRelations,
|
||||||
|
allowedRelations: allowedAdminPromotionRelations,
|
||||||
|
isList: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const listTransformQueryConfig = {
|
||||||
|
...retrieveTransformQueryConfig,
|
||||||
|
isList: true,
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IPromotionModuleService } from "@medusajs/types"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||||
|
|
||||||
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const promotionModuleService: IPromotionModuleService = req.scope.resolve(
|
||||||
|
ModuleRegistrationName.PROMOTION
|
||||||
|
)
|
||||||
|
|
||||||
|
const [promotions, count] = await promotionModuleService.listAndCount(
|
||||||
|
req.filterableFields,
|
||||||
|
req.listConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
const { limit, offset } = req.validatedQuery
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
count,
|
||||||
|
promotions,
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { IsOptional, IsString } from "class-validator"
|
||||||
|
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
||||||
|
|
||||||
|
export class AdminGetPromotionsPromotionParams extends FindParams {}
|
||||||
|
|
||||||
|
export class AdminGetPromotionsParams extends extendedFindParamsMixin({
|
||||||
|
limit: 100,
|
||||||
|
offset: 0,
|
||||||
|
}) {
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
code?: string
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { MiddlewaresConfig } from "../loaders/helpers/routing/types"
|
||||||
|
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
||||||
|
|
||||||
|
export const config: MiddlewaresConfig = {
|
||||||
|
routes: [...adminPromotionRoutesMiddlewares],
|
||||||
|
}
|
||||||
@@ -6,11 +6,12 @@ import { default as requireCustomerAuthentication } from "./require-customer-aut
|
|||||||
|
|
||||||
export { default as authenticate } from "./authenticate"
|
export { default as authenticate } from "./authenticate"
|
||||||
export { default as authenticateCustomer } from "./authenticate-customer"
|
export { default as authenticateCustomer } from "./authenticate-customer"
|
||||||
export { default as errorHandler } from "./error-handler"
|
|
||||||
export { default as wrapHandler } from "./await-middleware"
|
export { default as wrapHandler } from "./await-middleware"
|
||||||
export { canAccessBatchJob } from "./batch-job/can-access-batch-job"
|
export { canAccessBatchJob } from "./batch-job/can-access-batch-job"
|
||||||
export { getRequestedBatchJob } from "./batch-job/get-requested-batch-job"
|
export { getRequestedBatchJob } from "./batch-job/get-requested-batch-job"
|
||||||
export { doesConditionBelongToDiscount } from "./discount/does-condition-belong-to-discount"
|
export { doesConditionBelongToDiscount } from "./discount/does-condition-belong-to-discount"
|
||||||
|
export { default as errorHandler } from "./error-handler"
|
||||||
|
export { isFeatureFlagEnabled } from "./feature-flag-enabled"
|
||||||
export { default as normalizeQuery } from "./normalized-query"
|
export { default as normalizeQuery } from "./normalized-query"
|
||||||
export { default as requireCustomerAuthentication } from "./require-customer-authentication"
|
export { default as requireCustomerAuthentication } from "./require-customer-authentication"
|
||||||
export { transformBody } from "./transform-body"
|
export { transformBody } from "./transform-body"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import { AwilixContainer } from "awilix"
|
||||||
|
import bodyParser from "body-parser"
|
||||||
import { Express } from "express"
|
import { Express } from "express"
|
||||||
import qs from "qs"
|
import qs from "qs"
|
||||||
import bodyParser from "body-parser"
|
|
||||||
import routes from "../api"
|
import routes from "../api"
|
||||||
import { AwilixContainer } from "awilix"
|
|
||||||
import { ConfigModule } from "../types/global"
|
import { ConfigModule } from "../types/global"
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { asValue } from "awilix"
|
|||||||
import { createMedusaContainer } from "medusa-core-utils"
|
import { createMedusaContainer } from "medusa-core-utils"
|
||||||
import { track } from "medusa-telemetry"
|
import { track } from "medusa-telemetry"
|
||||||
import { EOL } from "os"
|
import { EOL } from "os"
|
||||||
|
import path from "path"
|
||||||
import requestIp from "request-ip"
|
import requestIp from "request-ip"
|
||||||
import { Connection } from "typeorm"
|
import { Connection } from "typeorm"
|
||||||
import { MedusaContainer } from "../types/global"
|
import { MedusaContainer } from "../types/global"
|
||||||
@@ -21,6 +22,7 @@ import loadConfig from "./config"
|
|||||||
import defaultsLoader from "./defaults"
|
import defaultsLoader from "./defaults"
|
||||||
import expressLoader from "./express"
|
import expressLoader from "./express"
|
||||||
import featureFlagsLoader from "./feature-flags"
|
import featureFlagsLoader from "./feature-flags"
|
||||||
|
import { RoutesLoader } from "./helpers/routing"
|
||||||
import Logger from "./logger"
|
import Logger from "./logger"
|
||||||
import loadMedusaApp, { mergeDefaultModules } from "./medusa-app"
|
import loadMedusaApp, { mergeDefaultModules } from "./medusa-app"
|
||||||
import modelsLoader from "./models"
|
import modelsLoader from "./models"
|
||||||
@@ -195,6 +197,22 @@ export default async ({
|
|||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO: Figure out why this is causing issues with test when placed inside ./api.ts
|
||||||
|
// Adding this here temporarily
|
||||||
|
// Test: (packages/medusa/src/api/routes/admin/currencies/update-currency.ts)
|
||||||
|
try {
|
||||||
|
/**
|
||||||
|
* Register the Medusa CORE API routes using the file based routing.
|
||||||
|
*/
|
||||||
|
await new RoutesLoader({
|
||||||
|
app: expressApp,
|
||||||
|
rootDir: path.join(__dirname, "../api-v2"),
|
||||||
|
configModule,
|
||||||
|
}).load()
|
||||||
|
} catch (err) {
|
||||||
|
throw Error("An error occurred while registering Medusa Core API Routes")
|
||||||
|
}
|
||||||
|
|
||||||
const pluginsActivity = Logger.activity(`Initializing plugins${EOL}`)
|
const pluginsActivity = Logger.activity(`Initializing plugins${EOL}`)
|
||||||
track("PLUGINS_INIT_STARTED")
|
track("PLUGINS_INIT_STARTED")
|
||||||
await pluginsLoader({
|
await pluginsLoader({
|
||||||
|
|||||||
+82
-1
@@ -1,5 +1,9 @@
|
|||||||
import { IPromotionModuleService } from "@medusajs/types"
|
import { IPromotionModuleService } from "@medusajs/types"
|
||||||
import { CampaignBudgetType, PromotionType } from "@medusajs/utils"
|
import {
|
||||||
|
ApplicationMethodType,
|
||||||
|
CampaignBudgetType,
|
||||||
|
PromotionType,
|
||||||
|
} from "@medusajs/utils"
|
||||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
import { initialize } from "../../../../src"
|
import { initialize } from "../../../../src"
|
||||||
import { createCampaigns } from "../../../__fixtures__/campaigns"
|
import { createCampaigns } from "../../../__fixtures__/campaigns"
|
||||||
@@ -680,6 +684,83 @@ describe("Promotion Service", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("listAndCount", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await createPromotions(repositoryManager, [
|
||||||
|
{
|
||||||
|
id: "promotion-id-1",
|
||||||
|
code: "PROMOTION_1",
|
||||||
|
type: PromotionType.STANDARD,
|
||||||
|
application_method: {
|
||||||
|
type: ApplicationMethodType.FIXED,
|
||||||
|
value: "200",
|
||||||
|
target_type: "items",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "promotion-id-2",
|
||||||
|
code: "PROMOTION_2",
|
||||||
|
type: PromotionType.STANDARD,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return all promotions and count", async () => {
|
||||||
|
const [promotions, count] = await service.listAndCount()
|
||||||
|
|
||||||
|
expect(count).toEqual(2)
|
||||||
|
expect(promotions).toEqual([
|
||||||
|
{
|
||||||
|
id: "promotion-id-1",
|
||||||
|
code: "PROMOTION_1",
|
||||||
|
campaign: null,
|
||||||
|
is_automatic: false,
|
||||||
|
type: "standard",
|
||||||
|
application_method: expect.any(String),
|
||||||
|
created_at: expect.any(Date),
|
||||||
|
updated_at: expect.any(Date),
|
||||||
|
deleted_at: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "promotion-id-2",
|
||||||
|
code: "PROMOTION_2",
|
||||||
|
campaign: null,
|
||||||
|
is_automatic: false,
|
||||||
|
type: "standard",
|
||||||
|
application_method: null,
|
||||||
|
created_at: expect.any(Date),
|
||||||
|
updated_at: expect.any(Date),
|
||||||
|
deleted_at: null,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return all promotions based on config select and relations param", async () => {
|
||||||
|
const [promotions, count] = await service.listAndCount(
|
||||||
|
{
|
||||||
|
id: ["promotion-id-1"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relations: ["application_method"],
|
||||||
|
select: ["code", "application_method.type"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(count).toEqual(1)
|
||||||
|
expect(promotions).toEqual([
|
||||||
|
{
|
||||||
|
id: "promotion-id-1",
|
||||||
|
code: "PROMOTION_1",
|
||||||
|
application_method: {
|
||||||
|
id: expect.any(String),
|
||||||
|
promotion: expect.any(Object),
|
||||||
|
type: "fixed",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("delete", () => {
|
describe("delete", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await createPromotions(repositoryManager)
|
await createPromotions(repositoryManager)
|
||||||
|
|||||||
@@ -2,6 +2,247 @@
|
|||||||
"namespaces": ["public"],
|
"namespaces": ["public"],
|
||||||
"name": "public",
|
"name": "public",
|
||||||
"tables": [
|
"tables": [
|
||||||
|
{
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"currency": {
|
||||||
|
"name": "currency",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"campaign_identifier": {
|
||||||
|
"name": "campaign_identifier",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"starts_at": {
|
||||||
|
"name": "starts_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"ends_at": {
|
||||||
|
"name": "ends_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "campaign",
|
||||||
|
"schema": "public",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"keyName": "IDX_campaign_identifier_unique",
|
||||||
|
"columnNames": ["campaign_identifier"],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "campaign_pkey",
|
||||||
|
"columnNames": ["id"],
|
||||||
|
"composite": false,
|
||||||
|
"primary": true,
|
||||||
|
"unique": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checks": [],
|
||||||
|
"foreignKeys": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"enumItems": ["spend", "usage"],
|
||||||
|
"mappedType": "enum"
|
||||||
|
},
|
||||||
|
"campaign_id": {
|
||||||
|
"name": "campaign_id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"name": "limit",
|
||||||
|
"type": "numeric",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"default": "null",
|
||||||
|
"mappedType": "decimal"
|
||||||
|
},
|
||||||
|
"used": {
|
||||||
|
"name": "used",
|
||||||
|
"type": "numeric",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"default": "0",
|
||||||
|
"mappedType": "decimal"
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "campaign_budget",
|
||||||
|
"schema": "public",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"columnNames": ["type"],
|
||||||
|
"composite": false,
|
||||||
|
"keyName": "IDX_campaign_budget_type",
|
||||||
|
"primary": false,
|
||||||
|
"unique": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columnNames": ["campaign_id"],
|
||||||
|
"composite": false,
|
||||||
|
"keyName": "campaign_budget_campaign_id_unique",
|
||||||
|
"primary": false,
|
||||||
|
"unique": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "campaign_budget_pkey",
|
||||||
|
"columnNames": ["id"],
|
||||||
|
"composite": false,
|
||||||
|
"primary": true,
|
||||||
|
"unique": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checks": [],
|
||||||
|
"foreignKeys": {
|
||||||
|
"campaign_budget_campaign_id_foreign": {
|
||||||
|
"constraintName": "campaign_budget_campaign_id_foreign",
|
||||||
|
"columnNames": ["campaign_id"],
|
||||||
|
"localTableName": "public.campaign_budget",
|
||||||
|
"referencedColumnNames": ["id"],
|
||||||
|
"referencedTableName": "public.campaign",
|
||||||
|
"updateRule": "cascade"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -22,6 +263,15 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
|
"campaign_id": {
|
||||||
|
"name": "campaign_id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
"is_automatic": {
|
"is_automatic": {
|
||||||
"name": "is_automatic",
|
"name": "is_automatic",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -108,7 +358,17 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"checks": [],
|
"checks": [],
|
||||||
"foreignKeys": {}
|
"foreignKeys": {
|
||||||
|
"promotion_campaign_id_foreign": {
|
||||||
|
"constraintName": "promotion_campaign_id_foreign",
|
||||||
|
"columnNames": ["campaign_id"],
|
||||||
|
"localTableName": "public.promotion",
|
||||||
|
"referencedColumnNames": ["id"],
|
||||||
|
"referencedTableName": "public.campaign",
|
||||||
|
"deleteRule": "set null",
|
||||||
|
"updateRule": "cascade"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": {
|
"columns": {
|
||||||
@@ -156,7 +416,7 @@
|
|||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": false,
|
"nullable": false,
|
||||||
"enumItems": ["order", "shipping", "item"],
|
"enumItems": ["order", "shipping_methods", "items"],
|
||||||
"mappedType": "enum"
|
"mappedType": "enum"
|
||||||
},
|
},
|
||||||
"allocation": {
|
"allocation": {
|
||||||
|
|||||||
+28
-3
@@ -1,9 +1,26 @@
|
|||||||
import { Migration } from "@mikro-orm/migrations"
|
import { Migration } from "@mikro-orm/migrations"
|
||||||
|
|
||||||
export class Migration20240102130345 extends Migration {
|
export class Migration20240117090706 extends Migration {
|
||||||
async up(): Promise<void> {
|
async up(): Promise<void> {
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'create table "promotion" ("id" text not null, "code" text not null, "is_automatic" boolean not null default false, "type" text check ("type" in (\'standard\', \'buyget\')) not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "promotion_pkey" primary key ("id"));'
|
'create table "campaign" ("id" text not null, "name" text not null, "description" text null, "currency" text null, "campaign_identifier" text not null, "starts_at" timestamptz null, "ends_at" timestamptz null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "campaign_pkey" primary key ("id"));'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table "campaign" add constraint "IDX_campaign_identifier_unique" unique ("campaign_identifier");'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'create table "campaign_budget" ("id" text not null, "type" text check ("type" in (\'spend\', \'usage\')) not null, "campaign_id" text not null, "limit" numeric null default null, "used" numeric not null default 0, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "campaign_budget_pkey" primary key ("id"));'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'create index "IDX_campaign_budget_type" on "campaign_budget" ("type");'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table "campaign_budget" add constraint "campaign_budget_campaign_id_unique" unique ("campaign_id");'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'create table "promotion" ("id" text not null, "code" text not null, "campaign_id" text null, "is_automatic" boolean not null default false, "type" text check ("type" in (\'standard\', \'buyget\')) not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "promotion_pkey" primary key ("id"));'
|
||||||
)
|
)
|
||||||
this.addSql('create index "IDX_promotion_code" on "promotion" ("code");')
|
this.addSql('create index "IDX_promotion_code" on "promotion" ("code");')
|
||||||
this.addSql('create index "IDX_promotion_type" on "promotion" ("type");')
|
this.addSql('create index "IDX_promotion_type" on "promotion" ("type");')
|
||||||
@@ -12,7 +29,7 @@ export class Migration20240102130345 extends Migration {
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'create table "application_method" ("id" text not null, "value" numeric null, "max_quantity" numeric null, "type" text check ("type" in (\'fixed\', \'percentage\')) not null, "target_type" text check ("target_type" in (\'order\', \'shipping\', \'item\')) not null, "allocation" text check ("allocation" in (\'each\', \'across\')) null, "promotion_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "application_method_pkey" primary key ("id"));'
|
'create table "application_method" ("id" text not null, "value" numeric null, "max_quantity" numeric null, "type" text check ("type" in (\'fixed\', \'percentage\')) not null, "target_type" text check ("target_type" in (\'order\', \'shipping_methods\', \'items\')) not null, "allocation" text check ("allocation" in (\'each\', \'across\')) null, "promotion_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "application_method_pkey" primary key ("id"));'
|
||||||
)
|
)
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'create index "IDX_application_method_type" on "application_method" ("type");'
|
'create index "IDX_application_method_type" on "application_method" ("type");'
|
||||||
@@ -52,6 +69,14 @@ export class Migration20240102130345 extends Migration {
|
|||||||
'create index "IDX_promotion_rule_promotion_rule_value_id" on "promotion_rule_value" ("promotion_rule_id");'
|
'create index "IDX_promotion_rule_promotion_rule_value_id" on "promotion_rule_value" ("promotion_rule_id");'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'alter table "campaign_budget" add constraint "campaign_budget_campaign_id_foreign" foreign key ("campaign_id") references "campaign" ("id") on update cascade;'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'alter table "promotion" add constraint "promotion_campaign_id_foreign" foreign key ("campaign_id") references "campaign" ("id") on update cascade on delete set null;'
|
||||||
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'alter table "application_method" add constraint "application_method_promotion_id_foreign" foreign key ("promotion_id") references "promotion" ("id") on update cascade;'
|
'alter table "application_method" add constraint "application_method_promotion_id_foreign" foreign key ("promotion_id") references "promotion" ("id") on update cascade;'
|
||||||
)
|
)
|
||||||
@@ -368,9 +368,7 @@ export default class PromotionModuleService<
|
|||||||
|
|
||||||
return await this.baseRepository_.serialize<PromotionTypes.PromotionDTO>(
|
return await this.baseRepository_.serialize<PromotionTypes.PromotionDTO>(
|
||||||
promotion,
|
promotion,
|
||||||
{
|
{ populate: true }
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,12 +386,31 @@ export default class PromotionModuleService<
|
|||||||
|
|
||||||
return await this.baseRepository_.serialize<PromotionTypes.PromotionDTO[]>(
|
return await this.baseRepository_.serialize<PromotionTypes.PromotionDTO[]>(
|
||||||
promotions,
|
promotions,
|
||||||
{
|
{ populate: true }
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
async listAndCount(
|
||||||
|
filters: PromotionTypes.FilterablePromotionProps = {},
|
||||||
|
config: FindConfig<PromotionTypes.PromotionDTO> = {},
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<[PromotionTypes.PromotionDTO[], number]> {
|
||||||
|
const [promotions, count] = await this.promotionService_.listAndCount(
|
||||||
|
filters,
|
||||||
|
config,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return [
|
||||||
|
await this.baseRepository_.serialize<PromotionTypes.PromotionDTO[]>(
|
||||||
|
promotions,
|
||||||
|
{ populate: true }
|
||||||
|
),
|
||||||
|
count,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
async create(
|
async create(
|
||||||
data: PromotionTypes.CreatePromotionDTO,
|
data: PromotionTypes.CreatePromotionDTO,
|
||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
@@ -899,9 +916,7 @@ export default class PromotionModuleService<
|
|||||||
|
|
||||||
return await this.baseRepository_.serialize<PromotionTypes.CampaignDTO>(
|
return await this.baseRepository_.serialize<PromotionTypes.CampaignDTO>(
|
||||||
campaign,
|
campaign,
|
||||||
{
|
{ populate: true }
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -919,9 +934,7 @@ export default class PromotionModuleService<
|
|||||||
|
|
||||||
return await this.baseRepository_.serialize<PromotionTypes.CampaignDTO[]>(
|
return await this.baseRepository_.serialize<PromotionTypes.CampaignDTO[]>(
|
||||||
campaigns,
|
campaigns,
|
||||||
{
|
{ populate: true }
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ export interface IPromotionModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<PromotionDTO[]>
|
): Promise<PromotionDTO[]>
|
||||||
|
|
||||||
|
listAndCount(
|
||||||
|
filters?: FilterablePromotionProps,
|
||||||
|
config?: FindConfig<PromotionDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<[PromotionDTO[], number]>
|
||||||
|
|
||||||
retrieve(
|
retrieve(
|
||||||
id: string,
|
id: string,
|
||||||
config?: FindConfig<PromotionDTO>,
|
config?: FindConfig<PromotionDTO>,
|
||||||
|
|||||||
@@ -8462,7 +8462,7 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@medusajs/promotion@workspace:packages/promotion":
|
"@medusajs/promotion@workspace:^, @medusajs/promotion@workspace:packages/promotion":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@medusajs/promotion@workspace:packages/promotion"
|
resolution: "@medusajs/promotion@workspace:packages/promotion"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -8637,7 +8637,7 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@medusajs/utils@^1.10.5, @medusajs/utils@^1.11.1, @medusajs/utils@^1.11.2, @medusajs/utils@^1.11.3, @medusajs/utils@^1.9.2, @medusajs/utils@^1.9.4, @medusajs/utils@workspace:packages/utils":
|
"@medusajs/utils@^1.10.5, @medusajs/utils@^1.11.1, @medusajs/utils@^1.11.2, @medusajs/utils@^1.11.3, @medusajs/utils@^1.9.2, @medusajs/utils@^1.9.4, @medusajs/utils@workspace:^, @medusajs/utils@workspace:packages/utils":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@medusajs/utils@workspace:packages/utils"
|
resolution: "@medusajs/utils@workspace:packages/utils"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -31241,6 +31241,9 @@ __metadata:
|
|||||||
"@medusajs/modules-sdk": "workspace:^"
|
"@medusajs/modules-sdk": "workspace:^"
|
||||||
"@medusajs/pricing": "workspace:^"
|
"@medusajs/pricing": "workspace:^"
|
||||||
"@medusajs/product": "workspace:^"
|
"@medusajs/product": "workspace:^"
|
||||||
|
"@medusajs/promotion": "workspace:^"
|
||||||
|
"@medusajs/types": "workspace:^"
|
||||||
|
"@medusajs/utils": "workspace:^"
|
||||||
babel-preset-medusa-package: "*"
|
babel-preset-medusa-package: "*"
|
||||||
faker: ^5.5.3
|
faker: ^5.5.3
|
||||||
jest: ^26.6.3
|
jest: ^26.6.3
|
||||||
|
|||||||
Reference in New Issue
Block a user