feat(core-flows,medusa,types,utils): adds update cart API with promotions (#6514)

what:

- adds update cart API
  - workflow
  - promotions
  - sales channel
  - region
  - customer
This commit is contained in:
Riqwan Thamir authored and GitHub committed 2024-02-27 12:09:30 +00:00
1 parent 608c10383a
commit f5c2256286
20 files changed
+435 -96

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
---
"@medusajs/core-flows": patch
"@medusajs/medusa": patch
"@medusajs/types": patch
"@medusajs/utils": patch
---
feat(core-flows,medusa,types,utils): adds update cart API with promotions
@@ -4,9 +4,11 @@ import {
ICustomerModuleService, ICustomerModuleService,
IPricingModuleService, IPricingModuleService,
IProductModuleService, IProductModuleService,
IPromotionModuleService,
IRegionModuleService, IRegionModuleService,
ISalesChannelModuleService, ISalesChannelModuleService,
} from "@medusajs/types" } from "@medusajs/types"
import { PromotionRuleOperator, PromotionType } from "@medusajs/utils"
import path from "path" import path from "path"
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app" import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
import { useApi } from "../../../../environment-helpers/use-api" import { useApi } from "../../../../environment-helpers/use-api"
@@ -30,6 +32,7 @@ describe("Store Carts API", () => {
let productModule: IProductModuleService let productModule: IProductModuleService
let pricingModule: IPricingModuleService let pricingModule: IPricingModuleService
let remoteLink let remoteLink
let promotionModule: IPromotionModuleService
let defaultRegion let defaultRegion
@@ -45,6 +48,7 @@ describe("Store Carts API", () => {
productModule = appContainer.resolve(ModuleRegistrationName.PRODUCT) productModule = appContainer.resolve(ModuleRegistrationName.PRODUCT)
pricingModule = appContainer.resolve(ModuleRegistrationName.PRICING) pricingModule = appContainer.resolve(ModuleRegistrationName.PRICING)
remoteLink = appContainer.resolve("remoteLink") remoteLink = appContainer.resolve("remoteLink")
promotionModule = appContainer.resolve(ModuleRegistrationName.PROMOTION)
}) })
afterAll(async () => { afterAll(async () => {
@@ -288,6 +292,171 @@ describe("Store Carts API", () => {
}) })
}) })
describe("POST /store/carts/:id", () => {
it("should update a cart with promo codes with a replace action", async () => {
const targetRules = [
{
attribute: "product_id",
operator: PromotionRuleOperator.IN,
values: ["prod_tshirt"],
},
]
const appliedPromotion = await promotionModule.create({
code: "PROMOTION_APPLIED",
type: PromotionType.STANDARD,
application_method: {
type: "fixed",
target_type: "items",
allocation: "each",
value: "300",
apply_to_quantity: 1,
max_quantity: 1,
target_rules: targetRules,
},
})
const createdPromotion = await promotionModule.create({
code: "PROMOTION_TEST",
type: PromotionType.STANDARD,
application_method: {
type: "fixed",
target_type: "items",
allocation: "across",
value: "1000",
apply_to_quantity: 1,
target_rules: targetRules,
},
})
const cart = await cartModuleService.create({
currency_code: "usd",
email: "tony@stark.com",
items: [
{
id: "item-1",
unit_price: 2000,
quantity: 1,
title: "Test item",
product_id: "prod_tshirt",
} as any,
],
})
const [adjustment] = await cartModuleService.addLineItemAdjustments([
{
code: appliedPromotion.code!,
amount: 300,
item_id: "item-1",
promotion_id: appliedPromotion.id,
},
])
const api = useApi() as any
// Should remove earlier adjustments from other promocodes
let updated = await api.post(`/store/carts/${cart.id}`, {
promo_codes: [createdPromotion.code],
})
expect(updated.status).toEqual(200)
expect(updated.data.cart).toEqual(
expect.objectContaining({
id: cart.id,
items: [
expect.objectContaining({
id: "item-1",
adjustments: [
expect.objectContaining({
id: expect.not.stringContaining(adjustment.id),
code: createdPromotion.code,
}),
],
}),
],
})
)
// Should remove all adjustments from other promo codes
updated = await api.post(`/store/carts/${cart.id}`, {
promo_codes: [],
})
expect(updated.status).toEqual(200)
expect(updated.data.cart).toEqual(
expect.objectContaining({
id: cart.id,
items: [
expect.objectContaining({
id: "item-1",
adjustments: [],
}),
],
})
)
})
it("should update a cart's region, sales channel and customer data", async () => {
const region = await regionModuleService.create({
name: "US",
currency_code: "usd",
})
const salesChannel = await scModuleService.create({
name: "Webshop",
})
const cart = await cartModuleService.create({
currency_code: "eur",
})
const api = useApi() as any
let updated = await api.post(`/store/carts/${cart.id}`, {
region_id: region.id,
email: "tony@stark.com",
sales_channel_id: salesChannel.id,
})
expect(updated.status).toEqual(200)
expect(updated.data.cart).toEqual(
expect.objectContaining({
id: cart.id,
currency_code: "usd",
region: expect.objectContaining({
id: region.id,
currency_code: "usd",
}),
email: "tony@stark.com",
customer: expect.objectContaining({
email: "tony@stark.com",
}),
sales_channel_id: salesChannel.id,
})
)
updated = await api.post(`/store/carts/${cart.id}`, {
email: null,
sales_channel_id: null,
})
expect(updated.status).toEqual(200)
expect(updated.data.cart).toEqual(
expect.objectContaining({
id: cart.id,
currency_code: "usd",
email: null,
customer_id: null,
region: expect.objectContaining({
id: region.id,
currency_code: "usd",
}),
sales_channel_id: null,
})
)
})
})
describe("GET /store/carts/:id", () => { describe("GET /store/carts/:id", () => {
it("should create and update a cart", async () => { it("should create and update a cart", async () => {
const region = await regionModuleService.create({ const region = await regionModuleService.create({
+2 -2
View File
@@ -14,11 +14,11 @@ export interface CreateCartDTO {
export interface UpdateCartDTO { export interface UpdateCartDTO {
id: string id: string
region_id?: string | null region_id?: string
customer_id?: string | null customer_id?: string | null
sales_channel_id?: string | null sales_channel_id?: string | null
email?: string | null email?: string | null
currency_code?: string | null currency_code?: string
metadata?: Record<string, unknown> | null metadata?: Record<string, unknown> | null
adjustments?: (CreateLineItemAdjustmentDTO | UpdateLineItemAdjustmentDTO)[] adjustments?: (CreateLineItemAdjustmentDTO | UpdateLineItemAdjustmentDTO)[]
@@ -4,13 +4,13 @@ import { validateEmail } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { StepResponse, createStep } from "@medusajs/workflows-sdk"
interface StepInput { interface StepInput {
customerId?: string customerId?: string | null
email?: string email?: string | null
} }
interface StepOutput { interface StepOutput {
customer?: CustomerDTO customer?: CustomerDTO | null
email?: string email?: string | null
} }
interface StepCompensateInput { interface StepCompensateInput {
@@ -22,11 +22,27 @@ export const findOrCreateCustomerStepId = "find-or-create-customer"
export const findOrCreateCustomerStep = createStep( export const findOrCreateCustomerStep = createStep(
findOrCreateCustomerStepId, findOrCreateCustomerStepId,
async (data: StepInput, { container }) => { async (data: StepInput, { container }) => {
if (
typeof data.customerId === undefined &&
typeof data.email === undefined
) {
return new StepResponse(
{
customer: undefined,
email: undefined,
},
{ customerWasCreated: false }
)
}
const service = container.resolve<ICustomerModuleService>( const service = container.resolve<ICustomerModuleService>(
ModuleRegistrationName.CUSTOMER ModuleRegistrationName.CUSTOMER
) )
const customerData: StepOutput = {} const customerData: StepOutput = {
customer: null,
email: null,
}
let customerWasCreated = false let customerWasCreated = false
if (data.customerId) { if (data.customerId) {
@@ -4,7 +4,7 @@ import { MedusaError } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { StepResponse, createStep } from "@medusajs/workflows-sdk"
interface StepInput { interface StepInput {
salesChannelId?: string salesChannelId?: string | null
} }
export const findSalesChannelStepId = "find-sales-channel" export const findSalesChannelStepId = "find-sales-channel"
@@ -15,6 +15,10 @@ export const findSalesChannelStep = createStep(
ModuleRegistrationName.SALES_CHANNEL ModuleRegistrationName.SALES_CHANNEL
) )
if (data.salesChannelId === null) {
return new StepResponse(null)
}
let salesChannel: SalesChannelDTO | undefined let salesChannel: SalesChannelDTO | undefined
if (data.salesChannelId) { if (data.salesChannelId) {
salesChannel = await salesChannelService.retrieve(data.salesChannelId) salesChannel = await salesChannelService.retrieve(data.salesChannelId)
@@ -1,12 +1,15 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { CartDTO, IPromotionModuleService } from "@medusajs/types" import { CartDTO, IPromotionModuleService } from "@medusajs/types"
import { deduplicate, isString } from "@medusajs/utils" import { PromotionActions, deduplicate, isString } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { StepResponse, createStep } from "@medusajs/workflows-sdk"
interface StepInput { interface StepInput {
cart: CartDTO cart: CartDTO
promoCodes: string[] promoCodes?: string[]
removePromotions: boolean action:
| PromotionActions.ADD
| PromotionActions.REMOVE
| PromotionActions.REPLACE
} }
export const getActionsToComputeFromPromotionsStepId = export const getActionsToComputeFromPromotionsStepId =
@@ -18,7 +21,11 @@ export const getActionsToComputeFromPromotionsStep = createStep(
ModuleRegistrationName.PROMOTION ModuleRegistrationName.PROMOTION
) )
const { removePromotions = false, promoCodes = [], cart } = data const { action = PromotionActions.ADD, promoCodes, cart } = data
if (!Array.isArray(promoCodes)) {
return new StepResponse([])
}
const appliedItemPromoCodes = cart.items const appliedItemPromoCodes = cart.items
?.map((item) => item.adjustments?.map((adjustment) => adjustment.code)) ?.map((item) => item.adjustments?.map((adjustment) => adjustment.code))
@@ -38,12 +45,16 @@ export const getActionsToComputeFromPromotionsStep = createStep(
...appliedShippingMethodPromoCodes, ...appliedShippingMethodPromoCodes,
]) ])
if (removePromotions) { if (action === PromotionActions.REMOVE) {
promotionCodesToApply = promotionCodesToApply.filter( promotionCodesToApply = promotionCodesToApply.filter(
(code) => !promoCodes.includes(code) (code) => !promoCodes.includes(code)
) )
} }
if (action === PromotionActions.REPLACE) {
promotionCodesToApply = promoCodes
}
const actionsToCompute = await promotionModuleService.computeActions( const actionsToCompute = await promotionModuleService.computeActions(
promotionCodesToApply, promotionCodesToApply,
cart as any cart as any
@@ -3,7 +3,7 @@ import { CartDTO, FindConfig, ICartModuleService } from "@medusajs/types"
import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { StepResponse, createStep } from "@medusajs/workflows-sdk"
interface StepInput { interface StepInput {
cartId: string id: string
config: FindConfig<CartDTO> config: FindConfig<CartDTO>
} }
@@ -15,7 +15,7 @@ export const retrieveCartStep = createStep(
ModuleRegistrationName.CART ModuleRegistrationName.CART
) )
const cart = await cartModuleService.retrieve(data.cartId, data.config) const cart = await cartModuleService.retrieve(data.id, data.config)
// TODO: remove this when cart handles totals calculation // TODO: remove this when cart handles totals calculation
cart.items = cart.items?.map((item) => { cart.items = cart.items?.map((item) => {
@@ -1,61 +1,53 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { import {
CartDTO,
FilterableCartProps,
ICartModuleService, ICartModuleService,
UpdateCartDataDTO, UpdateCartDTO,
UpdateCartWorkflowInputDTO,
} from "@medusajs/types" } from "@medusajs/types"
import { getSelectsAndRelationsFromObjectArray } from "@medusajs/utils" import { getSelectsAndRelationsFromObjectArray } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { StepResponse, createStep } from "@medusajs/workflows-sdk"
type UpdateCartsStepInput = {
selector: FilterableCartProps
update: UpdateCartDataDTO
}
export const updateCartsStepId = "update-carts" export const updateCartsStepId = "update-carts"
export const updateCartsStep = createStep( export const updateCartsStep = createStep(
updateCartsStepId, updateCartsStepId,
async (data: UpdateCartsStepInput, { container }) => { async (data: UpdateCartWorkflowInputDTO[], { container }) => {
const service = container.resolve<ICartModuleService>( const cartModule = container.resolve<ICartModuleService>(
ModuleRegistrationName.CART ModuleRegistrationName.CART
) )
const { selects, relations } = getSelectsAndRelationsFromObjectArray([ const { selects, relations } = getSelectsAndRelationsFromObjectArray(data)
data.update, const cartsBeforeUpdate = await cartModule.list(
]) { id: data.map((d) => d.id) },
{ select: selects, relations }
const prevCarts = await service.list(data.selector, {
select: selects,
relations,
})
const updatedCarts = await service.update(
data.selector as Partial<CartDTO>,
data.update
) )
return new StepResponse(updatedCarts, prevCarts) const updatedCart = await cartModule.update(data)
return new StepResponse(updatedCart, cartsBeforeUpdate)
}, },
async (previousCarts, { container }) => { async (cartsBeforeUpdate, { container }) => {
if (!previousCarts?.length) { if (!cartsBeforeUpdate) {
return return
} }
const service = container.resolve<ICartModuleService>( const cartModule = container.resolve<ICartModuleService>(
ModuleRegistrationName.CART ModuleRegistrationName.CART
) )
const toRestore = previousCarts.map((c) => ({ const dataToUpdate: UpdateCartDTO[] = []
id: c.id,
region_id: c.region_id,
customer_id: c.customer_id,
sales_channel_id: c.sales_channel_id,
email: c.email,
currency_code: c.currency_code,
metadata: c.metadata,
}))
await service.update(toRestore) for (const cart of cartsBeforeUpdate) {
dataToUpdate.push({
id: cart.id,
region_id: cart.region_id,
customer_id: cart.customer_id,
sales_channel_id: cart.sales_channel_id,
email: cart.email,
currency_code: cart.currency_code,
metadata: cart.metadata,
})
}
await cartModule.update(dataToUpdate)
} }
) )
@@ -1,4 +1,4 @@
export * from "./add-to-cart" export * from "./add-to-cart"
export * from "./create-carts" export * from "./create-carts"
export * from "./update-cart"
export * from "./update-cart-promotions" export * from "./update-cart-promotions"
export * from "./update-carts"
@@ -1,4 +1,5 @@
import { CartDTO } from "@medusajs/types" import { CartDTO } from "@medusajs/types"
import { PromotionActions } from "@medusajs/utils"
import { import {
WorkflowData, WorkflowData,
createWorkflow, createWorkflow,
@@ -17,7 +18,10 @@ import {
type WorkflowInput = { type WorkflowInput = {
promoCodes: string[] promoCodes: string[]
cartId: string cartId: string
removePromotions?: boolean action?:
| PromotionActions.ADD
| PromotionActions.REMOVE
| PromotionActions.REPLACE
} }
export const updateCartPromotionsWorkflowId = "update-cart-promotions" export const updateCartPromotionsWorkflowId = "update-cart-promotions"
@@ -25,7 +29,7 @@ export const updateCartPromotionsWorkflow = createWorkflow(
updateCartPromotionsWorkflowId, updateCartPromotionsWorkflowId,
(input: WorkflowData<WorkflowInput>): WorkflowData<CartDTO> => { (input: WorkflowData<WorkflowInput>): WorkflowData<CartDTO> => {
const retrieveCartInput = { const retrieveCartInput = {
cartId: input.cartId, id: input.cartId,
config: { config: {
relations: [ relations: [
"items", "items",
@@ -40,7 +44,7 @@ export const updateCartPromotionsWorkflow = createWorkflow(
const actions = getActionsToComputeFromPromotionsStep({ const actions = getActionsToComputeFromPromotionsStep({
cart, cart,
promoCodes: input.promoCodes, promoCodes: input.promoCodes,
removePromotions: input.removePromotions || false, action: input.action || PromotionActions.ADD,
}) })
const { const {
@@ -0,0 +1,112 @@
import { CartDTO, UpdateCartWorkflowInputDTO } from "@medusajs/types"
import { PromotionActions, isPresent } from "@medusajs/utils"
import {
WorkflowData,
createWorkflow,
parallelize,
transform,
} from "@medusajs/workflows-sdk"
import {
createLineItemAdjustmentsStep,
createShippingMethodAdjustmentsStep,
findOneOrAnyRegionStep,
findOrCreateCustomerStep,
findSalesChannelStep,
getActionsToComputeFromPromotionsStep,
prepareAdjustmentsFromPromotionActionsStep,
removeLineItemAdjustmentsStep,
removeShippingMethodAdjustmentsStep,
retrieveCartStep,
updateCartsStep,
} from "../steps"
export const updateCartWorkflowId = "update-cart"
export const updateCartWorkflow = createWorkflow(
updateCartWorkflowId,
(input: WorkflowData<UpdateCartWorkflowInputDTO>): WorkflowData<CartDTO> => {
const retrieveCartInput = {
id: input.id,
config: {
relations: [
"items",
"items.adjustments",
"shipping_methods",
"shipping_methods.adjustments",
],
},
}
const [salesChannel, region, customerData] = parallelize(
findSalesChannelStep({
salesChannelId: input.sales_channel_id,
}),
findOneOrAnyRegionStep({
regionId: input.region_id,
}),
findOrCreateCustomerStep({
customerId: input.customer_id,
email: input.email,
})
)
const cartInput = transform(
{ input, region, customerData, salesChannel },
(data) => {
const { promo_codes, ...updateCartData } = data.input
const data_ = { ...updateCartData }
if (isPresent(updateCartData.region_id)) {
data_.currency_code = data.region.currency_code
data_.region_id = data.region.id
}
if (
updateCartData.customer_id !== undefined ||
updateCartData.email !== undefined
) {
data_.customer_id = data.customerData.customer?.id || null
data_.email =
data.input?.email ?? (data.customerData.customer?.email || null)
}
if (updateCartData.sales_channel_id !== undefined) {
data_.sales_channel_id = data.salesChannel?.id || null
}
return data_
}
)
updateCartsStep([cartInput])
const cart = retrieveCartStep(retrieveCartInput)
const actions = getActionsToComputeFromPromotionsStep({
cart,
promoCodes: input.promo_codes,
action: PromotionActions.REPLACE,
})
const {
lineItemAdjustmentsToCreate,
lineItemAdjustmentIdsToRemove,
shippingMethodAdjustmentsToCreate,
shippingMethodAdjustmentIdsToRemove,
} = prepareAdjustmentsFromPromotionActionsStep({ actions })
parallelize(
removeLineItemAdjustmentsStep({ lineItemAdjustmentIdsToRemove }),
removeShippingMethodAdjustmentsStep({
shippingMethodAdjustmentIdsToRemove,
})
)
parallelize(
createLineItemAdjustmentsStep({ lineItemAdjustmentsToCreate }),
createShippingMethodAdjustmentsStep({ shippingMethodAdjustmentsToCreate })
)
return retrieveCartStep(retrieveCartInput).config({
name: "retrieve-cart-result-step",
})
}
)
@@ -1,20 +0,0 @@
import {
CartDTO,
FilterableCartProps,
UpdateCartDataDTO,
} from "@medusajs/types"
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { updateCartsStep } from "../steps/update-carts"
type WorkflowInput = {
selector: FilterableCartProps
update: UpdateCartDataDTO
}
export const updateCartsWorkflowId = "update-carts"
export const updateCartsWorkflow = createWorkflow(
updateCartsWorkflowId,
(input: WorkflowData<WorkflowInput>): WorkflowData<CartDTO[]> => {
return updateCartsStep(input)
}
)
@@ -1,4 +1,5 @@
import { updateCartPromotionsWorkflow } from "@medusajs/core-flows" import { updateCartPromotionsWorkflow } from "@medusajs/core-flows"
import { PromotionActions } from "@medusajs/utils"
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing" import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
import { StorePostCartsCartPromotionsReq } from "../../validators" import { StorePostCartsCartPromotionsReq } from "../../validators"
@@ -10,6 +11,7 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
input: { input: {
promoCodes: payload.promo_codes, promoCodes: payload.promo_codes,
cartId: req.params.id, cartId: req.params.id,
action: PromotionActions.ADD,
}, },
throwOnError: false, throwOnError: false,
}) })
@@ -29,7 +31,7 @@ export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => {
input: { input: {
promoCodes: payload.promo_codes, promoCodes: payload.promo_codes,
cartId: req.params.id, cartId: req.params.id,
removePromotions: true, action: PromotionActions.REMOVE,
}, },
throwOnError: false, throwOnError: false,
}) })
@@ -1,9 +1,9 @@
import { MedusaRequest, MedusaResponse } from "../../../../types/routing" import { updateCartWorkflow } from "@medusajs/core-flows"
import { UpdateCartDataDTO } from "@medusajs/types" import { UpdateCartDataDTO } from "@medusajs/types"
import { defaultStoreCartFields } from "../query-config"
import { remoteQueryObjectFromString } from "@medusajs/utils" import { remoteQueryObjectFromString } from "@medusajs/utils"
import { updateCartsWorkflow } from "@medusajs/core-flows"
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
import { defaultStoreCartFields } from "../query-config"
export const GET = async (req: MedusaRequest, res: MedusaResponse) => { export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const remoteQuery = req.scope.resolve("remoteQuery") const remoteQuery = req.scope.resolve("remoteQuery")
@@ -24,15 +24,13 @@ export const POST = async (
req: MedusaRequest<UpdateCartDataDTO>, req: MedusaRequest<UpdateCartDataDTO>,
res: MedusaResponse res: MedusaResponse
) => { ) => {
const updateCartWorkflow = updateCartsWorkflow(req.scope) const workflow = updateCartWorkflow(req.scope)
const workflowInput = { const { errors } = await workflow.run({
selector: { id: req.params.id }, input: {
update: req.validatedBody, ...(req.validatedBody as UpdateCartDataDTO),
} id: req.params.id,
},
const { result, errors } = await updateCartWorkflow.run({
input: workflowInput,
throwOnError: false, throwOnError: false,
}) })
@@ -40,5 +38,16 @@ export const POST = async (
throw errors[0].error throw errors[0].error
} }
res.status(200).json({ cart: result[0] }) const remoteQuery = req.scope.resolve("remoteQuery")
const query = remoteQueryObjectFromString({
entryPoint: "cart",
fields: defaultStoreCartFields,
})
const [updatedCart] = await remoteQuery(query, {
cart: { id: req.params.id },
})
res.status(200).json({ cart: updatedCart })
} }
@@ -10,8 +10,14 @@ export const defaultStoreCartFields = [
"items.title", "items.title",
"items.quantity", "items.quantity",
"items.unit_price", "items.unit_price",
"items.adjustments.id",
"items.adjustments.code",
"items.adjustments.amount",
"customer.id", "customer.id",
"customer.email", "customer.email",
"shipping_methods.adjustments.id",
"shipping_methods.adjustments.code",
"shipping_methods.adjustments.amount",
"shipping_address.id", "shipping_address.id",
"shipping_address.first_name", "shipping_address.first_name",
"shipping_address.last_name", "shipping_address.last_name",
@@ -40,20 +46,24 @@ export const defaultStoreCartFields = [
export const defaultStoreCartRelations = [ export const defaultStoreCartRelations = [
"items", "items",
"items.adjustments",
"region", "region",
"customer", "customer",
"shipping_address", "shipping_address",
"billing_address", "billing_address",
"shipping_methods", "shipping_methods",
"shipping_methods.adjustments",
] ]
export const allowedRelations = [ export const allowedRelations = [
"items", "items",
"items.adjustments",
"region", "region",
"customer", "customer",
"shipping_address", "shipping_address",
"billing_address", "billing_address",
"shipping_methods", "shipping_methods",
"shipping_methods.adjustments",
"sales_channel", "sales_channel",
] ]
@@ -81,14 +81,19 @@ export class StorePostCartsCartReq {
@IsType([AddressPayload, String]) @IsType([AddressPayload, String])
shipping_address?: AddressPayload | string shipping_address?: AddressPayload | string
@IsEmail()
@IsOptional() @IsOptional()
@IsString()
sales_channel_id?: string sales_channel_id?: string
@IsObject() @IsObject()
@IsOptional() @IsOptional()
metadata?: Record<string, unknown> metadata?: Record<string, unknown>
@IsOptional()
@IsArray()
@Type(() => String)
promo_codes?: string[]
// @IsOptional() // @IsOptional()
// @IsArray() // @IsArray()
// @ValidateNested({ each: true }) // @ValidateNested({ each: true })
+4 -4
View File
@@ -41,12 +41,12 @@ export interface CreateCartDTO {
} }
export interface UpdateCartDataDTO { export interface UpdateCartDataDTO {
region_id?: string | null region_id?: string
customer_id?: string | null customer_id?: string | null
sales_channel_id?: string | null sales_channel_id?: string | null
email?: string | null email?: string | null
currency_code?: string | null currency_code?: string
shipping_address_id?: string | null shipping_address_id?: string | null
billing_address_id?: string | null billing_address_id?: string | null
@@ -58,7 +58,7 @@ export interface UpdateCartDataDTO {
} }
export interface UpdateCartDTO extends UpdateCartDataDTO { export interface UpdateCartDTO extends UpdateCartDataDTO {
id?: string id: string
} }
/** CART END */ /** CART END */
@@ -176,7 +176,7 @@ export interface UpdateLineItemWithSelectorDTO {
export interface UpdateCartWithSelectorDTO { export interface UpdateCartWithSelectorDTO {
selector: Partial<CartDTO> selector: Partial<CartDTO>
data: UpdateCartDTO data: UpdateCartDataDTO
} }
export interface UpdateLineItemDTO export interface UpdateLineItemDTO
+11
View File
@@ -65,3 +65,14 @@ export interface AddToCartWorkflowInputDTO {
items: CreateCartCreateLineItemDTO[] items: CreateCartCreateLineItemDTO[]
cart: CartDTO cart: CartDTO
} }
export interface UpdateCartWorkflowInputDTO {
id: string
promo_codes?: string[]
region_id?: string
customer_id?: string | null
sales_channel_id?: string | null
email?: string | null
currency_code?: string
metadata?: Record<string, unknown> | null
}
+2 -2
View File
@@ -1,4 +1,5 @@
export * from "./address" export * from "./address"
export * from "./api-key"
export * from "./auth" export * from "./auth"
export * from "./bundles" export * from "./bundles"
export * from "./cache" export * from "./cache"
@@ -27,10 +28,9 @@ export * from "./sales-channel"
export * from "./search" export * from "./search"
export * from "./shared-context" export * from "./shared-context"
export * from "./stock-location" export * from "./stock-location"
export * from "./store"
export * from "./tax" export * from "./tax"
export * from "./totals" export * from "./totals"
export * from "./transaction-base" export * from "./transaction-base"
export * from "./user" export * from "./user"
export * from "./workflow" export * from "./workflow"
export * from "./api-key"
export * from "./store"
+6
View File
@@ -41,3 +41,9 @@ export enum ComputedActions {
REMOVE_SHIPPING_METHOD_ADJUSTMENT = "removeShippingMethodAdjustment", REMOVE_SHIPPING_METHOD_ADJUSTMENT = "removeShippingMethodAdjustment",
CAMPAIGN_BUDGET_EXCEEDED = "campaignBudgetExceeded", CAMPAIGN_BUDGET_EXCEEDED = "campaignBudgetExceeded",
} }
export enum PromotionActions {
ADD = "add",
REMOVE = "remove",
REPLACE = "replace",
}