feat(core-flows,medusa,types,utils): add rules to promotion endpoints + workflow (#6692)
* feat(core-flows,medusa,types,utils): add rules to promotion endpoints + workflow * chore: fix specs * chore: move input type to types package
This commit is contained in:
1 parent
02e784ce78
commit
640eccd5dd
23 files changed
+777
-179
No files matched your search
+61
-75
@@ -1084,8 +1084,8 @@ describe("Promotion Service", () => {
|
||||
expect(error.message).toEqual("promotion - id must be defined")
|
||||
})
|
||||
|
||||
it("should successfully create rules for a promotion", async () => {
|
||||
promotion = await service.addPromotionRules(promotion.id, [
|
||||
it("should successfully add rules to a promotion", async () => {
|
||||
const promotionRules = await service.addPromotionRules(promotion.id, [
|
||||
{
|
||||
attribute: "customer_group_id",
|
||||
operator: "in",
|
||||
@@ -1093,21 +1093,17 @@ describe("Promotion Service", () => {
|
||||
},
|
||||
])
|
||||
|
||||
expect(promotion).toEqual(
|
||||
expect(promotionRules).toEqual([
|
||||
expect.objectContaining({
|
||||
id: promotion.id,
|
||||
rules: [
|
||||
expect.objectContaining({
|
||||
attribute: "customer_group_id",
|
||||
operator: "in",
|
||||
values: [
|
||||
expect.objectContaining({ value: "VIP" }),
|
||||
expect.objectContaining({ value: "top100" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
)
|
||||
id: promotionRules[0].id,
|
||||
attribute: "customer_group_id",
|
||||
operator: "in",
|
||||
values: expect.arrayContaining([
|
||||
expect.objectContaining({ value: "VIP" }),
|
||||
expect.objectContaining({ value: "top100" }),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1160,31 +1156,28 @@ describe("Promotion Service", () => {
|
||||
})
|
||||
|
||||
it("should successfully create target rules for a promotion", async () => {
|
||||
promotion = await service.addPromotionTargetRules(promotion.id, [
|
||||
{
|
||||
const promotionRules = await service.addPromotionTargetRules(
|
||||
promotion.id,
|
||||
[
|
||||
{
|
||||
attribute: "customer_group_id",
|
||||
operator: "in",
|
||||
values: ["VIP", "top100"],
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
expect(promotionRules).toEqual([
|
||||
expect.objectContaining({
|
||||
id: promotionRules[0].id,
|
||||
attribute: "customer_group_id",
|
||||
operator: "in",
|
||||
values: ["VIP", "top100"],
|
||||
},
|
||||
values: expect.arrayContaining([
|
||||
expect.objectContaining({ value: "VIP" }),
|
||||
expect.objectContaining({ value: "top100" }),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
|
||||
expect(promotion).toEqual(
|
||||
expect.objectContaining({
|
||||
id: promotion.id,
|
||||
application_method: expect.objectContaining({
|
||||
target_rules: [
|
||||
expect.objectContaining({
|
||||
attribute: "customer_group_id",
|
||||
operator: "in",
|
||||
values: [
|
||||
expect.objectContaining({ value: "VIP" }),
|
||||
expect.objectContaining({ value: "top100" }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1250,7 +1243,7 @@ describe("Promotion Service", () => {
|
||||
})
|
||||
|
||||
it("should successfully create buy rules for a buyget promotion", async () => {
|
||||
promotion = await service.addPromotionBuyRules(promotion.id, [
|
||||
const promotionRules = await service.addPromotionBuyRules(promotion.id, [
|
||||
{
|
||||
attribute: "product.id",
|
||||
operator: "in",
|
||||
@@ -1258,30 +1251,17 @@ describe("Promotion Service", () => {
|
||||
},
|
||||
])
|
||||
|
||||
expect(promotion).toEqual(
|
||||
expect(promotionRules).toEqual([
|
||||
expect.objectContaining({
|
||||
id: promotion.id,
|
||||
application_method: expect.objectContaining({
|
||||
buy_rules: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
attribute: "product_collection.id",
|
||||
operator: "eq",
|
||||
values: expect.arrayContaining([
|
||||
expect.objectContaining({ value: "pcol_towel" }),
|
||||
]),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
attribute: "product.id",
|
||||
operator: "in",
|
||||
values: expect.arrayContaining([
|
||||
expect.objectContaining({ value: "prod_3" }),
|
||||
expect.objectContaining({ value: "prod_4" }),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
})
|
||||
)
|
||||
id: promotionRules[0].id,
|
||||
attribute: "product.id",
|
||||
operator: "in",
|
||||
values: expect.arrayContaining([
|
||||
expect.objectContaining({ value: "prod_3" }),
|
||||
expect.objectContaining({ value: "prod_4" }),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1337,14 +1317,16 @@ describe("Promotion Service", () => {
|
||||
expect(error.message).toEqual("promotion - id must be defined")
|
||||
})
|
||||
|
||||
it("should successfully create rules for a promotion", async () => {
|
||||
it("should successfully remove rules for a promotion", async () => {
|
||||
const [ruleId] = promotion.rules.map((rule) => rule.id)
|
||||
|
||||
promotion = await service.removePromotionRules(promotion.id, [
|
||||
{ id: ruleId },
|
||||
])
|
||||
await service.removePromotionRules(promotion.id, [{ id: ruleId }])
|
||||
|
||||
expect(promotion).toEqual(
|
||||
const updatedPromotion = await service.retrieve(promotion.id, {
|
||||
relations: ["rules", "rules.values"],
|
||||
})
|
||||
|
||||
expect(updatedPromotion).toEqual(
|
||||
expect.objectContaining({
|
||||
id: promotion.id,
|
||||
rules: [],
|
||||
@@ -1413,11 +1395,13 @@ describe("Promotion Service", () => {
|
||||
(rule) => rule.id
|
||||
)
|
||||
|
||||
promotion = await service.removePromotionTargetRules(promotion.id, [
|
||||
{ id: ruleId },
|
||||
])
|
||||
await service.removePromotionTargetRules(promotion.id, [{ id: ruleId }])
|
||||
|
||||
expect(promotion).toEqual(
|
||||
const updatedPromotion = await service.retrieve(promotion.id, {
|
||||
relations: ["application_method.target_rules.values"],
|
||||
})
|
||||
|
||||
expect(updatedPromotion).toEqual(
|
||||
expect.objectContaining({
|
||||
id: promotion.id,
|
||||
application_method: expect.objectContaining({
|
||||
@@ -1497,11 +1481,13 @@ describe("Promotion Service", () => {
|
||||
(rule) => rule.id
|
||||
)
|
||||
|
||||
promotion = await service.removePromotionBuyRules(promotion.id, [
|
||||
{ id: ruleId },
|
||||
])
|
||||
await service.removePromotionBuyRules(promotion.id, [{ id: ruleId }])
|
||||
|
||||
expect(promotion).toEqual(
|
||||
const updatedPromotion = await service.retrieve(promotion.id, {
|
||||
relations: ["application_method.buy_rules.values"],
|
||||
})
|
||||
|
||||
expect(updatedPromotion).toEqual(
|
||||
expect.objectContaining({
|
||||
id: promotion.id,
|
||||
application_method: expect.objectContaining({
|
||||
|
||||
@@ -755,19 +755,19 @@ export default class PromotionModuleService<
|
||||
promotionId: string,
|
||||
rulesData: PromotionTypes.CreatePromotionRuleDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<PromotionTypes.PromotionDTO> {
|
||||
): Promise<PromotionTypes.PromotionRuleDTO[]> {
|
||||
const promotion = await this.promotionService_.retrieve(promotionId)
|
||||
|
||||
await this.createPromotionRulesAndValues_(
|
||||
const createdPromotionRules = await this.createPromotionRulesAndValues_(
|
||||
rulesData,
|
||||
"promotions",
|
||||
promotion,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.retrieve(
|
||||
promotionId,
|
||||
{ relations: ["rules", "rules.values"] },
|
||||
return this.listPromotionRules(
|
||||
{ id: createdPromotionRules.map((r) => r.id) },
|
||||
{ relations: ["values"] },
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
@@ -777,7 +777,7 @@ export default class PromotionModuleService<
|
||||
promotionId: string,
|
||||
rulesData: PromotionTypes.CreatePromotionRuleDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<PromotionTypes.PromotionDTO> {
|
||||
): Promise<PromotionTypes.PromotionRuleDTO[]> {
|
||||
const promotion = await this.promotionService_.retrieve(promotionId, {
|
||||
relations: ["application_method"],
|
||||
})
|
||||
@@ -791,24 +791,16 @@ export default class PromotionModuleService<
|
||||
)
|
||||
}
|
||||
|
||||
await this.createPromotionRulesAndValues_(
|
||||
const createdPromotionRules = await this.createPromotionRulesAndValues_(
|
||||
rulesData,
|
||||
"method_target_rules",
|
||||
applicationMethod,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.retrieve(
|
||||
promotionId,
|
||||
{
|
||||
relations: [
|
||||
"rules",
|
||||
"rules.values",
|
||||
"application_method",
|
||||
"application_method.target_rules",
|
||||
"application_method.target_rules.values",
|
||||
],
|
||||
},
|
||||
return await this.listPromotionRules(
|
||||
{ id: createdPromotionRules.map((pr) => pr.id) },
|
||||
{ relations: ["values"] },
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
@@ -818,7 +810,7 @@ export default class PromotionModuleService<
|
||||
promotionId: string,
|
||||
rulesData: PromotionTypes.CreatePromotionRuleDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<PromotionTypes.PromotionDTO> {
|
||||
): Promise<PromotionTypes.PromotionRuleDTO[]> {
|
||||
const promotion = await this.promotionService_.retrieve(promotionId, {
|
||||
relations: ["application_method"],
|
||||
})
|
||||
@@ -832,24 +824,16 @@ export default class PromotionModuleService<
|
||||
)
|
||||
}
|
||||
|
||||
await this.createPromotionRulesAndValues_(
|
||||
const createdPromotionRules = await this.createPromotionRulesAndValues_(
|
||||
rulesData,
|
||||
"method_buy_rules",
|
||||
applicationMethod,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.retrieve(
|
||||
promotionId,
|
||||
{
|
||||
relations: [
|
||||
"rules",
|
||||
"rules.values",
|
||||
"application_method",
|
||||
"application_method.buy_rules",
|
||||
"application_method.buy_rules.values",
|
||||
],
|
||||
},
|
||||
return await this.listPromotionRules(
|
||||
{ id: createdPromotionRules.map((pr) => pr.id) },
|
||||
{ relations: ["values"] },
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
@@ -860,7 +844,25 @@ export default class PromotionModuleService<
|
||||
relationName: "promotions" | "method_target_rules" | "method_buy_rules",
|
||||
relation: Promotion | ApplicationMethod,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
) {
|
||||
): Promise<TPromotionRule[]> {
|
||||
const createdPromotionRules: TPromotionRule[] = []
|
||||
const promotion =
|
||||
relation instanceof ApplicationMethod ? relation.promotion : relation
|
||||
|
||||
if (!rulesData.length) {
|
||||
return []
|
||||
}
|
||||
|
||||
if (
|
||||
relationName === "method_buy_rules" &&
|
||||
promotion.type === PromotionType.STANDARD
|
||||
) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Can't add buy rules to a ${PromotionType.STANDARD} promotion`
|
||||
)
|
||||
}
|
||||
|
||||
validatePromotionRuleAttributes(rulesData)
|
||||
|
||||
for (const ruleData of rulesData) {
|
||||
@@ -875,6 +877,8 @@ export default class PromotionModuleService<
|
||||
sharedContext
|
||||
)
|
||||
|
||||
createdPromotionRules.push(createdPromotionRule)
|
||||
|
||||
const ruleValues = Array.isArray(values) ? values : [values]
|
||||
const promotionRuleValuesData = ruleValues.map((ruleValue) => ({
|
||||
value: ruleValue,
|
||||
@@ -886,6 +890,8 @@ export default class PromotionModuleService<
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
|
||||
return createdPromotionRules
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
@@ -893,14 +899,8 @@ export default class PromotionModuleService<
|
||||
promotionId: string,
|
||||
rulesData: PromotionTypes.RemovePromotionRuleDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<PromotionTypes.PromotionDTO> {
|
||||
): Promise<void> {
|
||||
await this.removePromotionRules_(promotionId, rulesData, sharedContext)
|
||||
|
||||
return await this.retrieve(
|
||||
promotionId,
|
||||
{ relations: ["rules", "rules.values"] },
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
@@ -932,27 +932,13 @@ export default class PromotionModuleService<
|
||||
promotionId: string,
|
||||
rulesData: PromotionTypes.RemovePromotionRuleDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<PromotionTypes.PromotionDTO> {
|
||||
): Promise<void> {
|
||||
await this.removeApplicationMethodRules_(
|
||||
promotionId,
|
||||
rulesData,
|
||||
ApplicationMethodRuleTypes.TARGET_RULES,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.retrieve(
|
||||
promotionId,
|
||||
{
|
||||
relations: [
|
||||
"rules",
|
||||
"rules.values",
|
||||
"application_method",
|
||||
"application_method.target_rules",
|
||||
"application_method.target_rules.values",
|
||||
],
|
||||
},
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
@@ -960,27 +946,13 @@ export default class PromotionModuleService<
|
||||
promotionId: string,
|
||||
rulesData: PromotionTypes.RemovePromotionRuleDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<PromotionTypes.PromotionDTO> {
|
||||
): Promise<void> {
|
||||
await this.removeApplicationMethodRules_(
|
||||
promotionId,
|
||||
rulesData,
|
||||
ApplicationMethodRuleTypes.BUY_RULES,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.retrieve(
|
||||
promotionId,
|
||||
{
|
||||
relations: [
|
||||
"rules",
|
||||
"rules.values",
|
||||
"application_method",
|
||||
"application_method.buy_rules",
|
||||
"application_method.buy_rules.values",
|
||||
],
|
||||
},
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
|
||||
Reference in new issue
Block a user