feat(core-flows,medusa,types): remove rules from promotion endpoints + workflows (#6696)
This commit is contained in:
7
.changeset/fifty-gorillas-lie.md
Normal file
7
.changeset/fifty-gorillas-lie.md
Normal 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
|
||||||
@@ -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)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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 }))
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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!),
|
||||||
|
}))
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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[]
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"],
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -7,3 +7,11 @@ export type AddPromotionRulesWorkflowDTO = {
|
|||||||
rules: CreatePromotionRuleDTO[]
|
rules: CreatePromotionRuleDTO[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type RemovePromotionRulesWorkflowDTO = {
|
||||||
|
rule_type: PromotionRuleTypes
|
||||||
|
data: {
|
||||||
|
id: string
|
||||||
|
rule_ids: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user