feat(core-flows,medusa,utils): promotion and campaign create/update endpoint (#6130)
what: - adds create endpoint for promotions including workflows and endpoint (RESOLVES CORE-1678) - adds update endpoint for promotions including workflows and endpoint (RESOLVES CORE-1679) - adds create endpoint for campaigns including workflows and endpoint (RESOLVES CORE-1684) - adds update endpoint for campaigns including workflows and endpoint (RESOLVES CORE-1685)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { updateCampaignsWorkflow } from "@medusajs/core-flows"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IPromotionModuleService } from "@medusajs/types"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||
@@ -17,3 +18,24 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
|
||||
res.status(200).json({ campaign })
|
||||
}
|
||||
|
||||
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
const updateCampaigns = updateCampaignsWorkflow(req.scope)
|
||||
const campaignsData = [
|
||||
{
|
||||
id: req.params.id,
|
||||
...(req.validatedBody || {}),
|
||||
},
|
||||
]
|
||||
|
||||
const { result, errors } = await updateCampaigns.run({
|
||||
input: { campaignsData },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
res.status(200).json({ campaign: result[0] })
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { MedusaV2Flag } from "@medusajs/utils"
|
||||
import { isFeatureFlagEnabled, transformQuery } from "../../../api/middlewares"
|
||||
import {
|
||||
isFeatureFlagEnabled,
|
||||
transformBody,
|
||||
transformQuery,
|
||||
} from "../../../api/middlewares"
|
||||
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||
import * as QueryConfig from "./query-config"
|
||||
import {
|
||||
AdminGetCampaignsCampaignParams,
|
||||
AdminGetCampaignsParams,
|
||||
AdminPostCampaignsCampaignReq,
|
||||
AdminPostCampaignsReq,
|
||||
} from "./validators"
|
||||
|
||||
export const adminCampaignRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
@@ -22,6 +28,11 @@ export const adminCampaignRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/campaigns",
|
||||
middlewares: [transformBody(AdminPostCampaignsReq)],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/campaigns/:id",
|
||||
@@ -32,4 +43,9 @@ export const adminCampaignRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/campaigns/:id",
|
||||
middlewares: [transformBody(AdminPostCampaignsCampaignReq)],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createCampaignsWorkflow } from "@medusajs/core-flows"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IPromotionModuleService } from "@medusajs/types"
|
||||
import { CreateCampaignDTO, IPromotionModuleService } from "@medusajs/types"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||
|
||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
@@ -21,3 +22,19 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
limit,
|
||||
})
|
||||
}
|
||||
|
||||
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
const createCampaigns = createCampaignsWorkflow(req.scope)
|
||||
const campaignsData = [req.validatedBody as CreateCampaignDTO]
|
||||
|
||||
const { result, errors } = await createCampaigns.run({
|
||||
input: { campaignsData },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
res.status(200).json({ campaign: result[0] })
|
||||
}
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
import { IsOptional, IsString } from "class-validator"
|
||||
import { CampaignBudgetType } from "@medusajs/utils"
|
||||
import { Type } from "class-transformer"
|
||||
import {
|
||||
IsArray,
|
||||
IsDateString,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
ValidateNested,
|
||||
} from "class-validator"
|
||||
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
||||
|
||||
export class AdminGetCampaignsCampaignParams extends FindParams {}
|
||||
@@ -15,3 +26,93 @@ export class AdminGetCampaignsParams extends extendedFindParamsMixin({
|
||||
@IsOptional()
|
||||
currency?: string
|
||||
}
|
||||
|
||||
export class AdminPostCampaignsReq {
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
name: string
|
||||
|
||||
@IsOptional()
|
||||
@IsNotEmpty()
|
||||
campaign_identifier?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
currency?: string
|
||||
|
||||
@IsOptional()
|
||||
@ValidateNested()
|
||||
@Type(() => CampaignBudget)
|
||||
budget?: CampaignBudget
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
starts_at?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
ends_at?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => IdObject)
|
||||
promotions?: IdObject[]
|
||||
}
|
||||
|
||||
export class IdObject {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
id: string
|
||||
}
|
||||
|
||||
export class CampaignBudget {
|
||||
@IsOptional()
|
||||
@IsEnum(CampaignBudgetType)
|
||||
type?: CampaignBudgetType
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
limit?: number
|
||||
}
|
||||
|
||||
export class AdminPostCampaignsCampaignReq {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
name?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsNotEmpty()
|
||||
campaign_identifier?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
currency?: string
|
||||
|
||||
@IsOptional()
|
||||
@ValidateNested()
|
||||
@Type(() => CampaignBudget)
|
||||
budget?: CampaignBudget
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
starts_at?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
ends_at?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => IdObject)
|
||||
promotions?: IdObject[]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { updatePromotionsWorkflow } from "@medusajs/core-flows"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IPromotionModuleService } from "@medusajs/types"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||
@@ -14,3 +15,24 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
|
||||
res.status(200).json({ promotion })
|
||||
}
|
||||
|
||||
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
const updatePromotions = updatePromotionsWorkflow(req.scope)
|
||||
const promotionsData = [
|
||||
{
|
||||
id: req.params.id,
|
||||
...(req.validatedBody || {}),
|
||||
},
|
||||
]
|
||||
|
||||
const { result, errors } = await updatePromotions.run({
|
||||
input: { promotionsData },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
res.status(200).json({ promotion: result[0] })
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { MedusaV2Flag } from "@medusajs/utils"
|
||||
import { isFeatureFlagEnabled, transformQuery } from "../../../api/middlewares"
|
||||
|
||||
import {
|
||||
isFeatureFlagEnabled,
|
||||
transformBody,
|
||||
transformQuery,
|
||||
} from "../../../api/middlewares"
|
||||
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||
import * as QueryConfig from "./query-config"
|
||||
import {
|
||||
AdminGetPromotionsParams,
|
||||
AdminGetPromotionsPromotionParams,
|
||||
AdminPostPromotionsPromotionReq,
|
||||
AdminPostPromotionsReq,
|
||||
} from "./validators"
|
||||
|
||||
export const adminPromotionRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
@@ -22,6 +29,11 @@ export const adminPromotionRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/promotions",
|
||||
middlewares: [transformBody(AdminPostPromotionsReq)],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/promotions/:id",
|
||||
@@ -32,4 +44,9 @@ export const adminPromotionRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/promotions/:id",
|
||||
middlewares: [transformBody(AdminPostPromotionsPromotionReq)],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createPromotionsWorkflow } from "@medusajs/core-flows"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { IPromotionModuleService } from "@medusajs/types"
|
||||
import { CreatePromotionDTO, IPromotionModuleService } from "@medusajs/types"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||
|
||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
@@ -21,3 +22,19 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
limit,
|
||||
})
|
||||
}
|
||||
|
||||
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
const createPromotions = createPromotionsWorkflow(req.scope)
|
||||
const promotionsData = [req.validatedBody as CreatePromotionDTO]
|
||||
|
||||
const { result, errors } = await createPromotions.run({
|
||||
input: { promotionsData },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
res.status(200).json({ promotion: result[0] })
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
import { IsOptional, IsString } from "class-validator"
|
||||
import {
|
||||
ApplicationMethodAllocation,
|
||||
ApplicationMethodTargetType,
|
||||
ApplicationMethodType,
|
||||
PromotionRuleOperator,
|
||||
PromotionType,
|
||||
} from "@medusajs/utils"
|
||||
import { Type } from "class-transformer"
|
||||
import {
|
||||
IsArray,
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Validate,
|
||||
ValidateNested,
|
||||
} from "class-validator"
|
||||
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
||||
import { XorConstraint } from "../../../types/validators/xor"
|
||||
import { AdminPostCampaignsReq } from "../campaigns/validators"
|
||||
|
||||
export class AdminGetPromotionsPromotionParams extends FindParams {}
|
||||
|
||||
@@ -11,3 +31,122 @@ export class AdminGetPromotionsParams extends extendedFindParamsMixin({
|
||||
@IsOptional()
|
||||
code?: string
|
||||
}
|
||||
|
||||
export class AdminPostPromotionsReq {
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
code: string
|
||||
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
is_automatic?: boolean
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(PromotionType)
|
||||
type?: PromotionType
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
campaign_id?: string
|
||||
|
||||
@IsOptional()
|
||||
@ValidateNested()
|
||||
@Type(() => AdminPostCampaignsReq)
|
||||
campaign?: AdminPostCampaignsReq
|
||||
|
||||
@IsNotEmpty()
|
||||
@ValidateNested()
|
||||
@Type(() => ApplicationMethod)
|
||||
application_method: ApplicationMethod
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => PromotionRule)
|
||||
rules?: PromotionRule[]
|
||||
}
|
||||
|
||||
export class PromotionRule {
|
||||
@IsEnum(PromotionRuleOperator)
|
||||
operator: PromotionRuleOperator
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string | null
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
attribute: string
|
||||
|
||||
@IsArray()
|
||||
@Type(() => String)
|
||||
values: string[]
|
||||
}
|
||||
|
||||
export class ApplicationMethod {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
value?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
max_quantity?: number
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(ApplicationMethodType)
|
||||
type?: ApplicationMethodType
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(ApplicationMethodTargetType)
|
||||
target_type?: ApplicationMethodTargetType
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(ApplicationMethodAllocation)
|
||||
allocation?: ApplicationMethodAllocation
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => PromotionRule)
|
||||
target_rules?: PromotionRule[]
|
||||
}
|
||||
|
||||
export class AdminPostPromotionsPromotionReq {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
code?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
is_automatic?: boolean
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(PromotionType)
|
||||
type?: PromotionType
|
||||
|
||||
@IsOptional()
|
||||
@Validate(XorConstraint, ["campaign"])
|
||||
@IsString()
|
||||
campaign_id?: string
|
||||
|
||||
@IsOptional()
|
||||
@Validate(XorConstraint, ["campaign_id"])
|
||||
@ValidateNested()
|
||||
@Type(() => AdminPostCampaignsReq)
|
||||
campaign?: AdminPostCampaignsReq
|
||||
|
||||
@IsOptional()
|
||||
@ValidateNested()
|
||||
@Type(() => ApplicationMethod)
|
||||
application_method?: ApplicationMethod
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => PromotionRule)
|
||||
rules?: PromotionRule[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user