feat: Line Items API Routes (#6478)
**What** - `POST /store/carts/:id/line-items` - `POST /store/carts/:id/line-items/:id` - `DELETE /store/carts/:id/line-items/:id` **Outstanding** - Integration tests - Module integrations: Payment, Fulfillment, Promotions Depends on #6475 and #6449.
This commit is contained in:
@@ -2,3 +2,5 @@ export * from "./add-to-cart"
|
||||
export * from "./create-carts"
|
||||
export * from "./update-cart"
|
||||
export * from "./update-cart-promotions"
|
||||
export * from "./update-line-item-in-cart"
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import { UpdateLineItemInCartWorkflowInputDTO } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { getVariantPriceSetsStep } from ".."
|
||||
import { updateLineItemsStep } from "../../line-item/steps"
|
||||
|
||||
// TODO: The UpdateLineItemsWorkflow are missing the following steps:
|
||||
// - Confirm inventory exists (inventory module)
|
||||
// - Validate shipping methods for new items (fulfillment module)
|
||||
// - Refresh line item adjustments (promotion module)
|
||||
// - Update payment sessions (payment module)
|
||||
|
||||
export const updateLineItemInCartWorkflowId = "update-line-item-in-cart"
|
||||
export const updateLineItemInCartWorkflow = createWorkflow(
|
||||
updateLineItemInCartWorkflowId,
|
||||
(input: WorkflowData<UpdateLineItemInCartWorkflowInputDTO>) => {
|
||||
const item = transform({ input }, (data) => data.input.item)
|
||||
|
||||
const pricingContext = transform({ cart: input.cart, item }, (data) => {
|
||||
return {
|
||||
currency_code: data.cart.currency_code,
|
||||
region_id: data.cart.region_id,
|
||||
customer_id: data.cart.customer_id,
|
||||
}
|
||||
})
|
||||
|
||||
const variantIds = transform({ input }, (data) => [
|
||||
data.input.item.variant_id!,
|
||||
])
|
||||
|
||||
const priceSets = getVariantPriceSetsStep({
|
||||
variantIds,
|
||||
context: pricingContext,
|
||||
})
|
||||
|
||||
const lineItemUpdate = transform({ input, priceSets, item }, (data) => {
|
||||
const price = data.priceSets[data.item.variant_id!].calculated_amount
|
||||
|
||||
return {
|
||||
data: {
|
||||
...data.input.update,
|
||||
unit_price: price,
|
||||
},
|
||||
selector: {
|
||||
id: data.input.item.id,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const result = updateLineItemsStep({
|
||||
data: lineItemUpdate.data,
|
||||
selector: lineItemUpdate.selector,
|
||||
})
|
||||
|
||||
const updatedItem = transform({ result }, (data) => data.result?.[0])
|
||||
|
||||
return updatedItem
|
||||
}
|
||||
)
|
||||
@@ -1,4 +1,6 @@
|
||||
export * from "./cart"
|
||||
export * from "./inventory"
|
||||
export * from "./line-item"
|
||||
export * from "./price-list"
|
||||
export * from "./product"
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./steps"
|
||||
export * from "./workflows"
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ICartModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const deleteLineItemsStepId = "delete-line-items"
|
||||
export const deleteLineItemsStep = createStep(
|
||||
deleteLineItemsStepId,
|
||||
async (ids: string[], { container }) => {
|
||||
const service = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
await service.removeLineItems(ids)
|
||||
|
||||
return new StepResponse(void 0, ids)
|
||||
},
|
||||
async (ids, { container }) => {
|
||||
if (!ids?.length) {
|
||||
return
|
||||
}
|
||||
const service = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
await service.restoreLineItems(ids)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./delete-line-items"
|
||||
export * from "./list-line-items"
|
||||
export * from "./update-line-items"
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
CartLineItemDTO,
|
||||
FilterableLineItemProps,
|
||||
FindConfig,
|
||||
ICartModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
filters: FilterableLineItemProps
|
||||
config?: FindConfig<CartLineItemDTO>
|
||||
}
|
||||
|
||||
export const listLineItemsStepId = "list-line-items"
|
||||
export const listLineItemsStep = createStep(
|
||||
listLineItemsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const service = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const items = await service.listLineItems(data.filters, data.config)
|
||||
|
||||
return new StepResponse(items)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,59 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
ICartModuleService,
|
||||
UpdateLineItemWithSelectorDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
getSelectsAndRelationsFromObjectArray,
|
||||
promiseAll,
|
||||
removeUndefined,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const updateLineItemsStepId = "update-line-items"
|
||||
export const updateLineItemsStep = createStep(
|
||||
updateLineItemsStepId,
|
||||
async (input: UpdateLineItemWithSelectorDTO, { container }) => {
|
||||
const service = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
|
||||
input.data,
|
||||
])
|
||||
|
||||
const itemsBefore = await service.listLineItems(input.selector, {
|
||||
select: selects,
|
||||
relations,
|
||||
})
|
||||
|
||||
const items = await service.updateLineItems(input.selector, input.data)
|
||||
|
||||
return new StepResponse(items, itemsBefore)
|
||||
},
|
||||
async (itemsBefore, { container }) => {
|
||||
if (!itemsBefore) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
)
|
||||
|
||||
await promiseAll(
|
||||
itemsBefore.map(async (i) =>
|
||||
service.updateLineItems(
|
||||
i.id,
|
||||
removeUndefined({
|
||||
quantity: i.quantity,
|
||||
title: i.title,
|
||||
metadata: i.metadata,
|
||||
unit_price: i.unit_price,
|
||||
tax_lines: i.tax_lines,
|
||||
adjustments: i.adjustments,
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { deleteLineItemsStep } from "../steps/delete-line-items"
|
||||
|
||||
type WorkflowInput = { ids: string[] }
|
||||
|
||||
// TODO: The DeleteLineItemsWorkflow are missing the following steps:
|
||||
// - Refresh/delete shipping methods (fulfillment module)
|
||||
// - Refresh line item adjustments (promotion module)
|
||||
// - Update payment sessions (payment module)
|
||||
|
||||
export const deleteLineItemsWorkflowId = "delete-line-items"
|
||||
export const deleteLineItemsWorkflow = createWorkflow(
|
||||
deleteLineItemsWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>) => {
|
||||
return deleteLineItemsStep(input.ids)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./delete-line-items"
|
||||
Reference in New Issue
Block a user