feat(core-flows,medusa,types): remove rules from promotion endpoints + workflows (#6696)

This commit is contained in:
Riqwan Thamir
2024-03-14 09:19:05 +01:00
committed by GitHub
parent 640eccd5dd
commit 04a532e5ef
16 changed files with 485 additions and 53 deletions

View File

@@ -0,0 +1,7 @@
---
"@medusajs/core-flows": patch
"@medusajs/medusa": patch
"@medusajs/types": patch
---
feat(core-flows,medusa,types): remove rules from promotion endpoints + workflows

View File

@@ -342,6 +342,194 @@ medusaIntegrationTestRunner({
) )
}) })
}) })
describe("DELETE /admin/promotions/:id/rules", () => {
it("should throw error when required params are missing", async () => {
const { response } = await api
.delete(`/admin/promotions/${standardPromotion.id}/rules`, {
...adminHeaders,
data: {},
})
.catch((e) => e)
expect(response.status).toEqual(400)
expect(response.data).toEqual({
type: "invalid_data",
message:
"each value in rule_ids must be a string, rule_ids should not be empty",
})
})
it("should throw error when promotion does not exist", async () => {
const { response } = await api
.delete(`/admin/promotions/does-not-exist/rules`, {
...adminHeaders,
data: { rule_ids: ["test-rule-id"] },
})
.catch((e) => e)
expect(response.status).toEqual(404)
expect(response.data).toEqual({
type: "not_found",
message: "Promotion with id: does-not-exist was not found",
})
})
it("should remove rules from a promotion successfully", async () => {
const response = await api.delete(
`/admin/promotions/${standardPromotion.id}/rules`,
{
...adminHeaders,
data: { rule_ids: [standardPromotion.rules[0].id] },
}
)
expect(response.status).toEqual(200)
expect(response.data).toEqual({
ids: [standardPromotion.rules[0].id],
object: "promotion-rule",
deleted: true,
})
const promotion = await promotionModule.retrieve(
standardPromotion.id,
{ relations: ["rules"] }
)
expect(promotion.rules!.length).toEqual(0)
})
})
describe("DELETE /admin/promotions/:id/target-rules", () => {
it("should throw error when required params are missing", async () => {
const { response } = await api
.delete(`/admin/promotions/${standardPromotion.id}/target-rules`, {
...adminHeaders,
data: {},
})
.catch((e) => e)
expect(response.status).toEqual(400)
expect(response.data).toEqual({
type: "invalid_data",
message:
"each value in rule_ids must be a string, rule_ids should not be empty",
})
})
it("should throw error when promotion does not exist", async () => {
const { response } = await api
.delete(`/admin/promotions/does-not-exist/target-rules`, {
...adminHeaders,
data: { rule_ids: ["test-rule-id"] },
})
.catch((e) => e)
expect(response.status).toEqual(404)
expect(response.data).toEqual({
type: "not_found",
message: "Promotion with id: does-not-exist was not found",
})
})
it("should remove target rules from a promotion successfully", async () => {
const ruleId = standardPromotion.application_method.target_rules[0].id
const response = await api.delete(
`/admin/promotions/${standardPromotion.id}/target-rules`,
{
...adminHeaders,
data: { rule_ids: [ruleId] },
}
)
expect(response.status).toEqual(200)
expect(response.data).toEqual({
ids: [ruleId],
object: "promotion-rule",
deleted: true,
})
const promotion = await promotionModule.retrieve(
standardPromotion.id,
{ relations: ["application_method.target_rules"] }
)
expect(promotion.application_method!.target_rules!.length).toEqual(0)
})
})
describe("DELETE /admin/promotions/:id/buy-rules", () => {
it("should throw error when required params are missing", async () => {
const { response } = await api
.delete(`/admin/promotions/${standardPromotion.id}/buy-rules`, {
...adminHeaders,
data: {},
})
.catch((e) => e)
expect(response.status).toEqual(400)
expect(response.data).toEqual({
type: "invalid_data",
message:
"each value in rule_ids must be a string, rule_ids should not be empty",
})
})
it("should throw error when promotion does not exist", async () => {
const { response } = await api
.delete(`/admin/promotions/does-not-exist/buy-rules`, {
...adminHeaders,
data: { rule_ids: ["test-rule-id"] },
})
.catch((e) => e)
expect(response.status).toEqual(404)
expect(response.data).toEqual({
type: "not_found",
message: "Promotion with id: does-not-exist was not found",
})
})
it("should remove buy rules from a promotion successfully", async () => {
const buyGetPromotion = await promotionModule.create({
code: "TEST_BUYGET",
type: PromotionType.BUYGET,
application_method: {
type: "fixed",
target_type: "items",
allocation: "across",
value: 100,
apply_to_quantity: 1,
buy_rules_min_quantity: 1,
buy_rules: [promotionRule],
target_rules: [promotionRule],
},
rules: [promotionRule],
})
const ruleId = buyGetPromotion!.application_method!.buy_rules![0].id
const response = await api.delete(
`/admin/promotions/${buyGetPromotion.id}/buy-rules`,
{
...adminHeaders,
data: { rule_ids: [ruleId] },
}
)
expect(response.status).toEqual(200)
expect(response.data).toEqual({
ids: [ruleId],
object: "promotion-rule",
deleted: true,
})
const promotion = await promotionModule.retrieve(buyGetPromotion.id, {
relations: ["application_method.buy_rules"],
})
expect(promotion.application_method!.buy_rules!.length).toEqual(0)
})
})
}) })
}, },
}) })

View File

@@ -39,7 +39,7 @@ export const addRulesToPromotionsStep = createStep(
return new StepResponse(promotionRules, { return new StepResponse(promotionRules, {
id: data.id, id: data.id,
ruleIds: createdPromotionRules.map((pr) => pr.id), promotionRuleIds: createdPromotionRules.map((pr) => pr.id),
buyRuleIds: createdPromotionBuyRules.map((pr) => pr.id), buyRuleIds: createdPromotionBuyRules.map((pr) => pr.id),
targetRuleIds: createdPromotionBuyRules.map((pr) => pr.id), targetRuleIds: createdPromotionBuyRules.map((pr) => pr.id),
}) })
@@ -49,28 +49,24 @@ export const addRulesToPromotionsStep = createStep(
return return
} }
const { id, ruleIds = [], buyRuleIds = [], targetRuleIds = [] } = data const {
id,
promotionRuleIds = [],
buyRuleIds = [],
targetRuleIds = [],
} = data
const promotionModule = container.resolve<IPromotionModuleService>( const promotionModule = container.resolve<IPromotionModuleService>(
ModuleRegistrationName.PROMOTION ModuleRegistrationName.PROMOTION
) )
ruleIds.length && promotionRuleIds.length &&
(await promotionModule.removePromotionRules( (await promotionModule.removePromotionRules(id, promotionRuleIds))
id,
ruleIds.map((id) => ({ id }))
))
buyRuleIds.length && buyRuleIds.length &&
(await promotionModule.removePromotionBuyRules( (await promotionModule.removePromotionBuyRules(id, buyRuleIds))
id,
buyRuleIds.map((id) => ({ id }))
))
targetRuleIds.length && targetRuleIds.length &&
(await promotionModule.removePromotionBuyRules( (await promotionModule.removePromotionBuyRules(id, targetRuleIds))
id,
targetRuleIds.map((id) => ({ id }))
))
} }
) )

View File

@@ -3,5 +3,6 @@ export * from "./create-campaigns"
export * from "./create-promotions" export * from "./create-promotions"
export * from "./delete-campaigns" export * from "./delete-campaigns"
export * from "./delete-promotions" export * from "./delete-promotions"
export * from "./remove-rules-from-promotions"
export * from "./update-campaigns" export * from "./update-campaigns"
export * from "./update-promotions" export * from "./update-promotions"

View File

@@ -0,0 +1,95 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import {
CreatePromotionRuleDTO,
IPromotionModuleService,
PromotionRuleDTO,
RemovePromotionRulesWorkflowDTO,
} from "@medusajs/types"
import { RuleType } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
export const removeRulesFromPromotionsStepId = "remove-rules-from-promotions"
export const removeRulesFromPromotionsStep = createStep(
removeRulesFromPromotionsStepId,
async (input: RemovePromotionRulesWorkflowDTO, { container }) => {
const { data, rule_type: ruleType } = input
const promotionModule = container.resolve<IPromotionModuleService>(
ModuleRegistrationName.PROMOTION
)
const promotion = await promotionModule.retrieve(data.id, {
relations: [
"rules.values",
"application_method.target_rules.values",
"application_method.buy_rules.values",
],
})
const promotionRulesToCreate: CreatePromotionRuleDTO[] = []
const buyRulesToCreate: CreatePromotionRuleDTO[] = []
const targetRulesToCreate: CreatePromotionRuleDTO[] = []
if (ruleType === RuleType.RULES) {
const rules = promotion.rules!
promotionRulesToCreate.push(...promotionRuleAttribute(rules))
await promotionModule.removePromotionRules(data.id, data.rule_ids)
}
if (ruleType === RuleType.BUY_RULES) {
const rules = promotion.application_method?.buy_rules!
buyRulesToCreate.push(...promotionRuleAttribute(rules))
await promotionModule.removePromotionBuyRules(data.id, data.rule_ids)
}
if (ruleType === RuleType.TARGET_RULES) {
const rules = promotion.application_method?.target_rules!
targetRulesToCreate.push(...promotionRuleAttribute(rules))
await promotionModule.removePromotionTargetRules(data.id, data.rule_ids)
}
return new StepResponse(null, {
id: data.id,
promotionRulesToCreate,
buyRulesToCreate,
targetRulesToCreate,
})
},
async (data, { container }) => {
if (!data) {
return
}
const {
id,
promotionRulesToCreate = [],
buyRulesToCreate = [],
targetRulesToCreate = [],
} = data
const promotionModule = container.resolve<IPromotionModuleService>(
ModuleRegistrationName.PROMOTION
)
promotionRulesToCreate.length &&
(await promotionModule.addPromotionRules(id, promotionRulesToCreate))
buyRulesToCreate.length &&
(await promotionModule.addPromotionBuyRules(id, buyRulesToCreate))
targetRulesToCreate.length &&
(await promotionModule.addPromotionBuyRules(id, targetRulesToCreate))
}
)
function promotionRuleAttribute(rules: PromotionRuleDTO[]) {
return rules.map((rule) => ({
description: rule.description!,
attribute: rule.attribute!,
operator: rule.operator!,
values: rule.values!.map((val) => val.value!),
}))
}

View File

@@ -3,5 +3,6 @@ export * from "./create-campaigns"
export * from "./create-promotions" export * from "./create-promotions"
export * from "./delete-campaigns" export * from "./delete-campaigns"
export * from "./delete-promotions" export * from "./delete-promotions"
export * from "./remove-rules-from-promotions"
export * from "./update-campaigns" export * from "./update-campaigns"
export * from "./update-promotions" export * from "./update-promotions"

View File

@@ -0,0 +1,14 @@
import { RemovePromotionRulesWorkflowDTO } from "@medusajs/types"
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { removeRulesFromPromotionsStep } from "../steps"
export const removeRulesFromPromotionsWorkflowId =
"remove-rules-from-promotions-workflow"
export const removeRulesFromPromotionsWorkflow = createWorkflow(
removeRulesFromPromotionsWorkflowId,
(
input: WorkflowData<RemovePromotionRulesWorkflowDTO>
): WorkflowData<void> => {
removeRulesFromPromotionsStep(input)
}
)

View File

@@ -1,4 +1,7 @@
import { addRulesToPromotionsWorkflow } from "@medusajs/core-flows" import {
addRulesToPromotionsWorkflow,
removeRulesFromPromotionsWorkflow,
} from "@medusajs/core-flows"
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IPromotionModuleService } from "@medusajs/types" import { IPromotionModuleService } from "@medusajs/types"
import { RuleType } from "@medusajs/utils" import { RuleType } from "@medusajs/utils"
@@ -10,7 +13,10 @@ import {
defaultAdminPromotionFields, defaultAdminPromotionFields,
defaultAdminPromotionRelations, defaultAdminPromotionRelations,
} from "../../query-config" } from "../../query-config"
import { AdminPostPromotionsPromotionRulesReq } from "../../validators" import {
AdminDeletePromotionsPromotionRulesReq,
AdminPostPromotionsPromotionRulesReq,
} from "../../validators"
export const POST = async ( export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostPromotionsPromotionRulesReq>, req: AuthenticatedMedusaRequest<AdminPostPromotionsPromotionRulesReq>,
@@ -22,7 +28,7 @@ export const POST = async (
input: { input: {
rule_type: RuleType.BUY_RULES, rule_type: RuleType.BUY_RULES,
data: { data: {
id: req.params.id, id,
...req.validatedBody, ...req.validatedBody,
}, },
}, },
@@ -44,3 +50,33 @@ export const POST = async (
res.status(200).json({ promotion }) res.status(200).json({ promotion })
} }
export const DELETE = async (
req: AuthenticatedMedusaRequest<AdminDeletePromotionsPromotionRulesReq>,
res: MedusaResponse
) => {
const id = req.params.id
const workflow = removeRulesFromPromotionsWorkflow(req.scope)
const validatedBody = req.validatedBody
const { errors } = await workflow.run({
input: {
rule_type: RuleType.BUY_RULES,
data: {
id,
...validatedBody,
},
},
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
res.status(200).json({
ids: validatedBody.rule_ids,
object: "promotion-rule",
deleted: true,
})
}

View File

@@ -1,4 +1,7 @@
import { addRulesToPromotionsWorkflow } from "@medusajs/core-flows" import {
addRulesToPromotionsWorkflow,
removeRulesFromPromotionsWorkflow,
} from "@medusajs/core-flows"
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IPromotionModuleService } from "@medusajs/types" import { IPromotionModuleService } from "@medusajs/types"
import { RuleType } from "@medusajs/utils" import { RuleType } from "@medusajs/utils"
@@ -10,7 +13,10 @@ import {
defaultAdminPromotionFields, defaultAdminPromotionFields,
defaultAdminPromotionRelations, defaultAdminPromotionRelations,
} from "../../query-config" } from "../../query-config"
import { AdminPostPromotionsPromotionRulesReq } from "../../validators" import {
AdminDeletePromotionsPromotionRulesReq,
AdminPostPromotionsPromotionRulesReq,
} from "../../validators"
export const POST = async ( export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostPromotionsPromotionRulesReq>, req: AuthenticatedMedusaRequest<AdminPostPromotionsPromotionRulesReq>,
@@ -23,7 +29,7 @@ export const POST = async (
input: { input: {
rule_type: RuleType.RULES, rule_type: RuleType.RULES,
data: { data: {
id: req.params.id, id,
...req.validatedBody, ...req.validatedBody,
}, },
}, },
@@ -45,3 +51,33 @@ export const POST = async (
res.status(200).json({ promotion }) res.status(200).json({ promotion })
} }
export const DELETE = async (
req: AuthenticatedMedusaRequest<AdminDeletePromotionsPromotionRulesReq>,
res: MedusaResponse
) => {
const id = req.params.id
const workflow = removeRulesFromPromotionsWorkflow(req.scope)
const validatedBody = req.validatedBody
const { errors } = await workflow.run({
input: {
rule_type: RuleType.RULES,
data: {
id,
...validatedBody,
},
},
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
res.status(200).json({
ids: validatedBody.rule_ids,
object: "promotion-rule",
deleted: true,
})
}

View File

@@ -1,4 +1,7 @@
import { addRulesToPromotionsWorkflow } from "@medusajs/core-flows" import {
addRulesToPromotionsWorkflow,
removeRulesFromPromotionsWorkflow,
} from "@medusajs/core-flows"
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IPromotionModuleService } from "@medusajs/types" import { IPromotionModuleService } from "@medusajs/types"
import { RuleType } from "@medusajs/utils" import { RuleType } from "@medusajs/utils"
@@ -10,7 +13,10 @@ import {
defaultAdminPromotionFields, defaultAdminPromotionFields,
defaultAdminPromotionRelations, defaultAdminPromotionRelations,
} from "../../query-config" } from "../../query-config"
import { AdminPostPromotionsPromotionRulesReq } from "../../validators" import {
AdminDeletePromotionsPromotionRulesReq,
AdminPostPromotionsPromotionRulesReq,
} from "../../validators"
export const POST = async ( export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostPromotionsPromotionRulesReq>, req: AuthenticatedMedusaRequest<AdminPostPromotionsPromotionRulesReq>,
@@ -22,7 +28,7 @@ export const POST = async (
input: { input: {
rule_type: RuleType.TARGET_RULES, rule_type: RuleType.TARGET_RULES,
data: { data: {
id: req.params.id, id,
...req.validatedBody, ...req.validatedBody,
}, },
}, },
@@ -44,3 +50,33 @@ export const POST = async (
res.status(200).json({ promotion }) res.status(200).json({ promotion })
} }
export const DELETE = async (
req: AuthenticatedMedusaRequest<AdminDeletePromotionsPromotionRulesReq>,
res: MedusaResponse
) => {
const id = req.params.id
const workflow = removeRulesFromPromotionsWorkflow(req.scope)
const validatedBody = req.validatedBody
const { errors } = await workflow.run({
input: {
rule_type: RuleType.TARGET_RULES,
data: {
id,
...validatedBody,
},
},
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
res.status(200).json({
ids: validatedBody.rule_ids,
object: "promotion-rule",
deleted: true,
})
}

View File

@@ -2,6 +2,7 @@ import * as QueryConfig from "./query-config"
import { transformBody, transformQuery } from "../../../api/middlewares" import { transformBody, transformQuery } from "../../../api/middlewares"
import { import {
AdminDeletePromotionsPromotionRulesReq,
AdminGetPromotionsParams, AdminGetPromotionsParams,
AdminGetPromotionsPromotionParams, AdminGetPromotionsPromotionParams,
AdminPostPromotionsPromotionReq, AdminPostPromotionsPromotionReq,
@@ -62,4 +63,19 @@ export const adminPromotionRoutesMiddlewares: MiddlewareRoute[] = [
matcher: "/admin/promotions/:id/buy-rules", matcher: "/admin/promotions/:id/buy-rules",
middlewares: [transformBody(AdminPostPromotionsPromotionRulesReq)], middlewares: [transformBody(AdminPostPromotionsPromotionRulesReq)],
}, },
{
method: ["DELETE"],
matcher: "/admin/promotions/:id/rules",
middlewares: [transformBody(AdminDeletePromotionsPromotionRulesReq)],
},
{
method: ["DELETE"],
matcher: "/admin/promotions/:id/target-rules",
middlewares: [transformBody(AdminDeletePromotionsPromotionRulesReq)],
},
{
method: ["DELETE"],
matcher: "/admin/promotions/:id/buy-rules",
middlewares: [transformBody(AdminDeletePromotionsPromotionRulesReq)],
},
] ]

View File

@@ -8,6 +8,7 @@ import {
} from "@medusajs/utils" } from "@medusajs/utils"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { import {
ArrayNotEmpty,
IsArray, IsArray,
IsBoolean, IsBoolean,
IsEnum, IsEnum,
@@ -221,3 +222,9 @@ export class AdminPostPromotionsPromotionRulesReq {
@Type(() => PromotionRule) @Type(() => PromotionRule)
rules: PromotionRule[] rules: PromotionRule[]
} }
export class AdminDeletePromotionsPromotionRulesReq {
@ArrayNotEmpty()
@IsString({ each: true })
rule_ids: string[]
}

View File

@@ -1318,9 +1318,9 @@ describe("Promotion Service", () => {
}) })
it("should successfully remove rules for a promotion", async () => { it("should successfully remove rules for a promotion", async () => {
const [ruleId] = promotion.rules.map((rule) => rule.id) const ruleIds = promotion.rules.map((rule) => rule.id)
await service.removePromotionRules(promotion.id, [{ id: ruleId }]) await service.removePromotionRules(promotion.id, ruleIds)
const updatedPromotion = await service.retrieve(promotion.id, { const updatedPromotion = await service.retrieve(promotion.id, {
relations: ["rules", "rules.values"], relations: ["rules", "rules.values"],
@@ -1391,11 +1391,11 @@ describe("Promotion Service", () => {
}) })
it("should successfully create rules for a promotion", async () => { it("should successfully create rules for a promotion", async () => {
const [ruleId] = promotion.application_method.target_rules.map( const ruleIds = promotion.application_method.target_rules.map(
(rule) => rule.id (rule) => rule.id
) )
await service.removePromotionTargetRules(promotion.id, [{ id: ruleId }]) await service.removePromotionTargetRules(promotion.id, ruleIds)
const updatedPromotion = await service.retrieve(promotion.id, { const updatedPromotion = await service.retrieve(promotion.id, {
relations: ["application_method.target_rules.values"], relations: ["application_method.target_rules.values"],
@@ -1477,11 +1477,11 @@ describe("Promotion Service", () => {
}) })
it("should successfully remove rules for a promotion", async () => { it("should successfully remove rules for a promotion", async () => {
const [ruleId] = promotion.application_method.buy_rules.map( const ruleIds = promotion.application_method.buy_rules.map(
(rule) => rule.id (rule) => rule.id
) )
await service.removePromotionBuyRules(promotion.id, [{ id: ruleId }]) await service.removePromotionBuyRules(promotion.id, ruleIds)
const updatedPromotion = await service.retrieve(promotion.id, { const updatedPromotion = await service.retrieve(promotion.id, {
relations: ["application_method.buy_rules.values"], relations: ["application_method.buy_rules.values"],

View File

@@ -897,32 +897,26 @@ export default class PromotionModuleService<
@InjectManager("baseRepository_") @InjectManager("baseRepository_")
async removePromotionRules( async removePromotionRules(
promotionId: string, promotionId: string,
rulesData: PromotionTypes.RemovePromotionRuleDTO[], ruleIds: string[],
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<void> { ): Promise<void> {
await this.removePromotionRules_(promotionId, rulesData, sharedContext) await this.removePromotionRules_(promotionId, ruleIds, sharedContext)
} }
@InjectTransactionManager("baseRepository_") @InjectTransactionManager("baseRepository_")
protected async removePromotionRules_( protected async removePromotionRules_(
promotionId: string, promotionId: string,
rulesData: PromotionTypes.RemovePromotionRuleDTO[], ruleIds: string[],
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<void> { ): Promise<void> {
const promotionRuleIdsToRemove = rulesData.map((ruleData) => ruleData.id)
const promotion = await this.promotionService_.retrieve( const promotion = await this.promotionService_.retrieve(
promotionId, promotionId,
{ relations: ["rules"] }, { relations: ["rules"] },
sharedContext sharedContext
) )
const existingPromotionRuleIds = promotion.rules const existingRuleIds = promotion.rules.map((rule) => rule.id)
.toArray() const idsToRemove = ruleIds.filter((id) => existingRuleIds.includes(id))
.map((rule) => rule.id)
const idsToRemove = promotionRuleIdsToRemove.filter((ruleId) =>
existingPromotionRuleIds.includes(ruleId)
)
await this.promotionRuleService_.delete(idsToRemove, sharedContext) await this.promotionRuleService_.delete(idsToRemove, sharedContext)
} }
@@ -930,12 +924,12 @@ export default class PromotionModuleService<
@InjectManager("baseRepository_") @InjectManager("baseRepository_")
async removePromotionTargetRules( async removePromotionTargetRules(
promotionId: string, promotionId: string,
rulesData: PromotionTypes.RemovePromotionRuleDTO[], ruleIds: string[],
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<void> { ): Promise<void> {
await this.removeApplicationMethodRules_( await this.removeApplicationMethodRules_(
promotionId, promotionId,
rulesData, ruleIds,
ApplicationMethodRuleTypes.TARGET_RULES, ApplicationMethodRuleTypes.TARGET_RULES,
sharedContext sharedContext
) )
@@ -944,12 +938,12 @@ export default class PromotionModuleService<
@InjectManager("baseRepository_") @InjectManager("baseRepository_")
async removePromotionBuyRules( async removePromotionBuyRules(
promotionId: string, promotionId: string,
rulesData: PromotionTypes.RemovePromotionRuleDTO[], ruleIds: string[],
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<void> { ): Promise<void> {
await this.removeApplicationMethodRules_( await this.removeApplicationMethodRules_(
promotionId, promotionId,
rulesData, ruleIds,
ApplicationMethodRuleTypes.BUY_RULES, ApplicationMethodRuleTypes.BUY_RULES,
sharedContext sharedContext
) )
@@ -958,13 +952,12 @@ export default class PromotionModuleService<
@InjectTransactionManager("baseRepository_") @InjectTransactionManager("baseRepository_")
protected async removeApplicationMethodRules_( protected async removeApplicationMethodRules_(
promotionId: string, promotionId: string,
rulesData: PromotionTypes.RemovePromotionRuleDTO[], ruleIds: string[],
relation: relation:
| ApplicationMethodRuleTypes.TARGET_RULES | ApplicationMethodRuleTypes.TARGET_RULES
| ApplicationMethodRuleTypes.BUY_RULES, | ApplicationMethodRuleTypes.BUY_RULES,
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<void> { ): Promise<void> {
const promotionRuleIds = rulesData.map((ruleData) => ruleData.id)
const promotion = await this.promotionService_.retrieve( const promotion = await this.promotionService_.retrieve(
promotionId, promotionId,
{ relations: [`application_method.${relation}`] }, { relations: [`application_method.${relation}`] },
@@ -981,8 +974,7 @@ export default class PromotionModuleService<
} }
const targetRuleIdsToRemove = applicationMethod[relation] const targetRuleIdsToRemove = applicationMethod[relation]
.toArray() .filter((rule) => ruleIds.includes(rule.id))
.filter((rule) => promotionRuleIds.includes(rule.id))
.map((rule) => rule.id) .map((rule) => rule.id)
await this.promotionRuleService_.delete( await this.promotionRuleService_.delete(

View File

@@ -12,7 +12,6 @@ import {
FilterablePromotionProps, FilterablePromotionProps,
PromotionDTO, PromotionDTO,
PromotionRuleDTO, PromotionRuleDTO,
RemovePromotionRuleDTO,
UpdatePromotionDTO, UpdatePromotionDTO,
} from "./common" } from "./common"
import { CreateCampaignDTO, UpdateCampaignDTO } from "./mutations" import { CreateCampaignDTO, UpdateCampaignDTO } from "./mutations"
@@ -99,19 +98,19 @@ export interface IPromotionModuleService extends IModuleService {
removePromotionRules( removePromotionRules(
promotionId: string, promotionId: string,
rulesData: RemovePromotionRuleDTO[], ruleIds: string[],
sharedContext?: Context sharedContext?: Context
): Promise<void> ): Promise<void>
removePromotionTargetRules( removePromotionTargetRules(
promotionId: string, promotionId: string,
rulesData: RemovePromotionRuleDTO[], ruleIds: string[],
sharedContext?: Context sharedContext?: Context
): Promise<void> ): Promise<void>
removePromotionBuyRules( removePromotionBuyRules(
promotionId: string, promotionId: string,
rulesData: RemovePromotionRuleDTO[], ruleIds: string[],
sharedContext?: Context sharedContext?: Context
): Promise<void> ): Promise<void>

View File

@@ -7,3 +7,11 @@ export type AddPromotionRulesWorkflowDTO = {
rules: CreatePromotionRuleDTO[] rules: CreatePromotionRuleDTO[]
} }
} }
export type RemovePromotionRulesWorkflowDTO = {
rule_type: PromotionRuleTypes
data: {
id: string
rule_ids: string[]
}
}