feat(medusa): Add endpoints specific to DiscountConditions (#1355)

This commit is contained in:
Oliver Windall Juhl
2022-05-13 12:42:23 +02:00
committed by GitHub
parent a69b52e031
commit 9ca45ea492
20 changed files with 1433 additions and 159 deletions
@@ -0,0 +1,107 @@
import { IsOptional, IsString } from "class-validator"
import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "."
import { Discount } from "../../../../models/discount"
import { DiscountConditionOperator } from "../../../../models/discount-condition"
import { DiscountService } from "../../../../services"
import DiscountConditionService from "../../../../services/discount-condition"
import { AdminUpsertConditionsReq } from "../../../../types/discount"
import { getRetrieveConfig } from "../../../../utils/get-query-config"
import { validator } from "../../../../utils/validator"
/**
* @oas [post] /discounts/{discount_id}/conditions
* operationId: "PostDiscountsDiscountConditions"
* summary: "Creates a DiscountCondition"
* x-authenticated: true
* parameters:
* - (path) discount_id=* {string} The id of the Product.
* - (query) expand {string} (Comma separated) Which fields should be expanded in each product of the result.
* - (query) fields {string} (Comma separated) Which fields should be included in each product of the result.
* description: "Creates a DiscountCondition"
* requestBody:
* content:
* application/json:
* schema:
* properties:
* operator:
* description: Operator of the condition
* type: string
* items:
* properties:
* products:
* type: array
* description: list of products
* product_types:
* type: array
* description: list of product types
* product_collections:
* type: array
* description: list of product collections
* product_tags:
* type: array
* description: list of product tags
* customer_groups:
* type: array
* description: list of customer_groups
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id } = req.params
const validatedCondition = await validator(
AdminPostDiscountsDiscountConditions,
req.body
)
const validatedParams = await validator(
AdminPostDiscountsDiscountConditionsParams,
req.query
)
const conditionService: DiscountConditionService = req.scope.resolve(
"discountConditionService"
)
const discountService: DiscountService = req.scope.resolve("discountService")
let discount = await discountService.retrieve(discount_id)
await conditionService.upsertCondition({
...validatedCondition,
rule_id: discount.rule_id,
})
const config = getRetrieveConfig<Discount>(
defaultAdminDiscountsFields,
defaultAdminDiscountsRelations,
validatedParams?.fields?.split(",") as (keyof Discount)[],
validatedParams?.expand?.split(",")
)
discount = await discountService.retrieve(discount.id, config)
res.status(200).json({ discount })
}
export class AdminPostDiscountsDiscountConditions extends AdminUpsertConditionsReq {
@IsString()
operator: DiscountConditionOperator
}
export class AdminPostDiscountsDiscountConditionsParams {
@IsString()
@IsOptional()
expand?: string
@IsString()
@IsOptional()
fields?: string
}
@@ -83,8 +83,6 @@ import { AdminPostDiscountsDiscountParams } from "./update-discount"
export default async (req, res) => {
const validated = await validator(AdminPostDiscountsReq, req.body)
console.log(validated.rule.conditions)
const validatedParams = await validator(
AdminPostDiscountsDiscountParams,
req.query
@@ -0,0 +1,109 @@
import { IsOptional, IsString } from "class-validator"
import { MedusaError } from "medusa-core-utils"
import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "."
import { Discount } from "../../../../models"
import { DiscountService } from "../../../../services"
import DiscountConditionService from "../../../../services/discount-condition"
import { getRetrieveConfig } from "../../../../utils/get-query-config"
import { validator } from "../../../../utils/validator"
/**
* @oas [delete] /discounts/{discount_id}/conditions/{condition_id}
* operationId: "DeleteDiscountsDiscountConditionsCondition"
* summary: "Delete a DiscountCondition"
* description: "Deletes a DiscountCondition"
* x-authenticated: true
* parameters:
* - (path) id=* {string} The id of the Discount
* - (path) condition_id=* {string} The id of the DiscountCondition
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* id:
* type: string
* description: The id of the deleted DiscountCondition
* object:
* type: string
* description: The type of the object that was deleted.
* deleted:
* type: boolean
* discount:
* type: object
* description: The Discount to which the condition used to belong
*/
export default async (req, res) => {
const { discount_id, condition_id } = req.params
const validatedParams = await validator(
AdminDeleteDiscountsDiscountConditionsConditionParams,
req.query
)
const conditionService: DiscountConditionService = req.scope.resolve(
"discountConditionService"
)
const condition = await conditionService
.retrieve(condition_id)
.catch(() => void 0)
if (!condition) {
// resolves idempotently in case of non-existing condition
return res.json({
id: condition_id,
object: "discount-condition",
deleted: true,
})
}
const discountService: DiscountService = req.scope.resolve("discountService")
let discount = await discountService.retrieve(discount_id, {
relations: ["rule", "rule.conditions"],
})
const existsOnDiscount = discount.rule.conditions.some(
(c) => c.id === condition_id
)
if (!existsOnDiscount) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Condition with id ${condition_id} does not belong to Discount with id ${discount_id}`
)
}
await conditionService.delete(condition_id)
const config = getRetrieveConfig<Discount>(
defaultAdminDiscountsFields,
defaultAdminDiscountsRelations,
validatedParams?.fields?.split(",") as (keyof Discount)[],
validatedParams?.expand?.split(",")
)
discount = await discountService.retrieve(discount_id, config)
res.json({
id: condition_id,
object: "discount-condition",
deleted: true,
discount,
})
}
export class AdminDeleteDiscountsDiscountConditionsConditionParams {
@IsString()
@IsOptional()
expand?: string
@IsString()
@IsOptional()
fields?: string
}
@@ -49,6 +49,20 @@ export default (app) => {
middlewares.wrap(require("./remove-region").default)
)
// Discount condition management
route.post(
"/:discount_id/conditions/:condition_id",
middlewares.wrap(require("./update-condition").default)
)
route.post(
"/:discount_id/conditions",
middlewares.wrap(require("./create-condition").default)
)
route.delete(
"/:discount_id/conditions/:condition_id",
middlewares.wrap(require("./delete-condition").default)
)
return app
}
@@ -88,12 +102,15 @@ export type AdminDiscountsListRes = PaginatedResponse & {
}
export * from "./add-region"
export * from "./create-condition"
export * from "./create-discount"
export * from "./create-dynamic-code"
export * from "./delete-condition"
export * from "./delete-discount"
export * from "./delete-dynamic-code"
export * from "./get-discount"
export * from "./get-discount-by-code"
export * from "./list-discounts"
export * from "./remove-region"
export * from "./update-condition"
export * from "./update-discount"
@@ -0,0 +1,109 @@
import { IsOptional, IsString } from "class-validator"
import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "."
import { Discount } from "../../../../models/discount"
import { DiscountService } from "../../../../services"
import DiscountConditionService from "../../../../services/discount-condition"
import { AdminUpsertConditionsReq } from "../../../../types/discount"
import { getRetrieveConfig } from "../../../../utils/get-query-config"
import { validator } from "../../../../utils/validator"
/**
* @oas [post] /discounts/{discount_id}/conditions/{condition_id}
* operationId: "PostDiscountsDiscountConditionsCondition"
* summary: "Updates a DiscountCondition"
* x-authenticated: true
* parameters:
* - (path) discount_id=* {string} The id of the Product.
* - (query) expand {string} (Comma separated) Which fields should be expanded in each product of the result.
* - (query) fields {string} (Comma separated) Which fields should be included in each product of the result.
* description: "Updates a DiscountCondition"
* requestBody:
* content:
* application/json:
* required:
* - id
* schema:
* properties:
* items:
* properties:
* products:
* type: array
* description: list of products
* product_types:
* type: array
* description: list of product types
* product_collections:
* type: array
* description: list of product collections
* product_tags:
* type: array
* description: list of product tags
* customer_groups:
* type: array
* description: list of customer_groups
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id, condition_id } = req.params
const validatedCondition = await validator(
AdminPostDiscountsDiscountConditionsCondition,
req.body
)
const validatedParams = await validator(
AdminPostDiscountsDiscountConditionsConditionParams,
req.query
)
const conditionService: DiscountConditionService = req.scope.resolve(
"discountConditionService"
)
const condition = await conditionService.retrieve(condition_id)
const discountService: DiscountService = req.scope.resolve("discountService")
let discount = await discountService.retrieve(discount_id)
const updateObj = {
...validatedCondition,
rule_id: discount.rule_id,
id: condition.id,
}
await conditionService.upsertCondition(updateObj)
const config = getRetrieveConfig<Discount>(
defaultAdminDiscountsFields,
defaultAdminDiscountsRelations,
validatedParams?.fields?.split(",") as (keyof Discount)[],
validatedParams?.expand?.split(",")
)
discount = await discountService.retrieve(discount.id, config)
res.status(200).json({ discount })
}
export class AdminPostDiscountsDiscountConditionsCondition extends AdminUpsertConditionsReq {}
export class AdminPostDiscountsDiscountConditionsConditionParams {
@IsString()
@IsOptional()
expand?: string
@IsString()
@IsOptional()
fields?: string
}