chore: complete cart part 2 (#7227)
This commit is contained in:
committed by
GitHub
parent
c32a31e139
commit
aba194de9a
@@ -8,6 +8,7 @@ interface StepInput {
|
||||
items: {
|
||||
inventory_item_id: string
|
||||
required_quantity: number
|
||||
allow_backorder: boolean
|
||||
quantity: number
|
||||
location_ids: string[]
|
||||
}[]
|
||||
@@ -23,6 +24,10 @@ export const confirmInventoryStep = createStep(
|
||||
|
||||
// TODO: Should be bulk
|
||||
const promises = data.items.map(async (item) => {
|
||||
if (item.allow_backorder) {
|
||||
return true
|
||||
}
|
||||
|
||||
const itemQuantity = item.required_quantity * item.quantity
|
||||
|
||||
return await inventoryService.confirmInventory(
|
||||
|
||||
@@ -37,6 +37,26 @@ export const completeCartFields = [
|
||||
"original_shipping_tax_total",
|
||||
"original_shipping_tax_subtotal",
|
||||
"original_shipping_total",
|
||||
"raw_total",
|
||||
"raw_subtotal",
|
||||
"raw_tax_total",
|
||||
"raw_discount_total",
|
||||
"raw_discount_tax_total",
|
||||
"raw_original_total",
|
||||
"raw_original_tax_total",
|
||||
"raw_item_total",
|
||||
"raw_item_subtotal",
|
||||
"raw_item_tax_total",
|
||||
"raw_sales_channel_id",
|
||||
"raw_original_item_total",
|
||||
"raw_original_item_subtotal",
|
||||
"raw_original_item_tax_total",
|
||||
"raw_shipping_total",
|
||||
"raw_shipping_subtotal",
|
||||
"raw_shipping_tax_total",
|
||||
"raw_original_shipping_tax_total",
|
||||
"raw_original_shipping_tax_subtotal",
|
||||
"raw_original_shipping_total",
|
||||
"items.*",
|
||||
"items.tax_lines.*",
|
||||
"items.adjustments.*",
|
||||
@@ -49,4 +69,37 @@ export const completeCartFields = [
|
||||
"region.*",
|
||||
"payment_collection.*",
|
||||
"payment_collection.payment_sessions.*",
|
||||
"items.variant.id",
|
||||
"items.variant.manage_inventory",
|
||||
"items.variant.allow_backorder",
|
||||
"items.variant.inventory_items.inventory_item_id",
|
||||
"items.variant.inventory_items.required_quantity",
|
||||
"items.variant.inventory_items.inventory.location_levels.stock_locations.id",
|
||||
"items.variant.inventory_items.inventory.location_levels.stock_locations.name",
|
||||
"items.variant.inventory_items.inventory.location_levels.stock_locations.sales_channels.id",
|
||||
"items.variant.inventory_items.inventory.location_levels.stock_locations.sales_channels.name",
|
||||
]
|
||||
|
||||
export const productVariantsFields = [
|
||||
"id",
|
||||
"title",
|
||||
"sku",
|
||||
"manage_inventory",
|
||||
"allow_backorder",
|
||||
"barcode",
|
||||
"product.id",
|
||||
"product.title",
|
||||
"product.description",
|
||||
"product.subtitle",
|
||||
"product.thumbnail",
|
||||
"product.type",
|
||||
"product.collection",
|
||||
"product.handle",
|
||||
"calculated_price.calculated_amount",
|
||||
"inventory_items.inventory_item_id",
|
||||
"inventory_items.required_quantity",
|
||||
"inventory_items.inventory.location_levels.stock_locations.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.name",
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.name",
|
||||
]
|
||||
|
||||
@@ -7,14 +7,22 @@ interface ConfirmInventoryPreparationInput {
|
||||
inventory_item_id: string
|
||||
required_quantity: number
|
||||
}[]
|
||||
items: { variant_id?: string; quantity: BigNumberInput }[]
|
||||
variants: { id: string; manage_inventory?: boolean }[]
|
||||
items: {
|
||||
variant_id?: string
|
||||
quantity: BigNumberInput
|
||||
}[]
|
||||
variants: {
|
||||
id: string
|
||||
manage_inventory?: boolean
|
||||
allow_backorder?: boolean
|
||||
}[]
|
||||
location_ids: string[]
|
||||
}
|
||||
|
||||
interface ConfirmInventoryItem {
|
||||
inventory_item_id: string
|
||||
required_quantity: number
|
||||
allow_backorder: boolean
|
||||
quantity: number
|
||||
location_ids: string[]
|
||||
}
|
||||
@@ -31,7 +39,7 @@ export const prepareConfirmInventoryInput = ({
|
||||
|
||||
const variantsMap = new Map<
|
||||
string,
|
||||
{ id: string; manage_inventory?: boolean }
|
||||
ConfirmInventoryPreparationInput["variants"][0]
|
||||
>(variants.map((v) => [v.id, v]))
|
||||
|
||||
const itemsToConfirm: ConfirmInventoryItem[] = []
|
||||
@@ -57,6 +65,7 @@ export const prepareConfirmInventoryInput = ({
|
||||
itemsToConfirm.push({
|
||||
inventory_item_id: variantInventoryItem.inventory_item_id,
|
||||
required_quantity: variantInventoryItem.required_quantity,
|
||||
allow_backorder: !!variant.allow_backorder,
|
||||
quantity: item.quantity as number, // TODO: update type to BigNumberInput
|
||||
location_ids: location_ids,
|
||||
})
|
||||
|
||||
@@ -7,18 +7,16 @@ import {
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { useRemoteQueryStep } from "../../../common/steps/use-remote-query"
|
||||
import {
|
||||
addToCartStep,
|
||||
confirmInventoryStep,
|
||||
refreshCartShippingMethodsStep,
|
||||
} from "../steps"
|
||||
import { addToCartStep, refreshCartShippingMethodsStep } from "../steps"
|
||||
import { refreshCartPromotionsStep } from "../steps/refresh-cart-promotions"
|
||||
import { updateTaxLinesStep } from "../steps/update-tax-lines"
|
||||
import { cartFieldsForRefreshSteps } from "../utils/fields"
|
||||
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
|
||||
import {
|
||||
cartFieldsForRefreshSteps,
|
||||
productVariantsFields,
|
||||
} from "../utils/fields"
|
||||
import { prepareLineItemData } from "../utils/prepare-line-item-data"
|
||||
import { confirmVariantInventoryWorkflow } from "./confirm-variant-inventory"
|
||||
import { refreshPaymentCollectionForCartStep } from "./refresh-payment-collection"
|
||||
|
||||
// TODO: The AddToCartWorkflow are missing the following steps:
|
||||
@@ -43,32 +41,7 @@ export const addToCartWorkflow = createWorkflow(
|
||||
|
||||
const variants = useRemoteQueryStep({
|
||||
entry_point: "variants",
|
||||
fields: [
|
||||
"id",
|
||||
"title",
|
||||
"sku",
|
||||
"barcode",
|
||||
"manage_inventory",
|
||||
"product.id",
|
||||
"product.title",
|
||||
"product.description",
|
||||
"product.subtitle",
|
||||
"product.thumbnail",
|
||||
"product.type",
|
||||
"product.collection",
|
||||
"product.handle",
|
||||
|
||||
"calculated_price.calculated_amount",
|
||||
|
||||
"inventory_items.inventory_item_id",
|
||||
"inventory_items.required_quantity",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.name",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.name",
|
||||
],
|
||||
fields: productVariantsFields,
|
||||
variables: {
|
||||
id: variantIds,
|
||||
calculated_price: {
|
||||
@@ -78,71 +51,14 @@ export const addToCartWorkflow = createWorkflow(
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const confirmInventoryInput = transform({ input, variants }, (data) => {
|
||||
const managedVariants = data.variants.filter((v) => v.manage_inventory)
|
||||
if (!managedVariants.length) {
|
||||
return { items: [] }
|
||||
}
|
||||
|
||||
const productVariantInventoryItems: any[] = []
|
||||
|
||||
const stockLocations = data.variants
|
||||
.map((v) => v.inventory_items)
|
||||
.flat()
|
||||
.map((ii) => {
|
||||
productVariantInventoryItems.push({
|
||||
variant_id: ii.variant_id,
|
||||
inventory_item_id: ii.inventory_item_id,
|
||||
required_quantity: ii.required_quantity,
|
||||
})
|
||||
|
||||
return ii.inventory.location_levels
|
||||
})
|
||||
.flat()
|
||||
.map((ll) => ll.stock_locations)
|
||||
.flat()
|
||||
|
||||
const salesChannelId = data.input.cart.sales_channel_id
|
||||
if (salesChannelId) {
|
||||
const salesChannels = stockLocations
|
||||
.map((sl) => sl.sales_channels)
|
||||
.flat()
|
||||
.filter((sc) => sc.id === salesChannelId)
|
||||
|
||||
if (!salesChannels.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Sales channel ${salesChannelId} is not associated with any stock locations.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const priceNotFound: string[] = data.variants
|
||||
.filter((v) => !v.calculated_price)
|
||||
.map((v) => v.id)
|
||||
|
||||
if (priceNotFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variants with IDs ${priceNotFound.join(", ")} do not have a price`
|
||||
)
|
||||
}
|
||||
|
||||
const items = prepareConfirmInventoryInput({
|
||||
product_variant_inventory_items: productVariantInventoryItems,
|
||||
location_ids: stockLocations.map((l) => l.id),
|
||||
items: data.input.items!,
|
||||
variants: data.variants.map((v) => ({
|
||||
id: v.id,
|
||||
manage_inventory: v.manage_inventory,
|
||||
})),
|
||||
})
|
||||
|
||||
return { items }
|
||||
confirmVariantInventoryWorkflow.runAsStep({
|
||||
input: {
|
||||
sales_channel_id: input.cart.sales_channel_id as string,
|
||||
variants,
|
||||
items: input.items,
|
||||
},
|
||||
})
|
||||
|
||||
confirmInventoryStep(confirmInventoryInput)
|
||||
|
||||
const lineItems = transform({ input, variants }, (data) => {
|
||||
const items = (data.input.items ?? []).map((item) => {
|
||||
const variant = data.variants.find((v) => v.id === item.variant_id)!
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { CompleteCartWorkflowInputDTO, OrderDTO } from "@medusajs/types"
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { OrderDTO } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../../common"
|
||||
import { createOrderFromCartStep } from "../steps"
|
||||
import { updateTaxLinesStep } from "../steps/update-tax-lines"
|
||||
import { completeCartFields } from "../utils/fields"
|
||||
import { confirmVariantInventoryWorkflow } from "./confirm-variant-inventory"
|
||||
|
||||
/*
|
||||
- [] Create Tax Lines
|
||||
@@ -19,9 +24,7 @@ import { completeCartFields } from "../utils/fields"
|
||||
export const completeCartWorkflowId = "complete-cart"
|
||||
export const completeCartWorkflow = createWorkflow(
|
||||
completeCartWorkflowId,
|
||||
(
|
||||
input: WorkflowData<CompleteCartWorkflowInputDTO>
|
||||
): WorkflowData<OrderDTO> => {
|
||||
(input: WorkflowData<any>): WorkflowData<OrderDTO> => {
|
||||
const cart = useRemoteQueryStep({
|
||||
entry_point: "cart",
|
||||
fields: completeCartFields,
|
||||
@@ -29,6 +32,37 @@ export const completeCartWorkflow = createWorkflow(
|
||||
list: false,
|
||||
})
|
||||
|
||||
const { variants, items, sales_channel_id } = transform(
|
||||
{ cart },
|
||||
(data) => {
|
||||
const allItems: any[] = []
|
||||
const allVariants: any[] = []
|
||||
data.cart.items.forEach((item) => {
|
||||
allItems.push({
|
||||
id: item.id,
|
||||
quantity: item.quantity,
|
||||
})
|
||||
|
||||
allVariants.push(item.variant)
|
||||
})
|
||||
|
||||
return {
|
||||
variants: allVariants,
|
||||
items: allItems,
|
||||
sales_channel_id: data.cart.sales_channel_id,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
confirmVariantInventoryWorkflow.runAsStep({
|
||||
input: {
|
||||
ignore_price_check: true,
|
||||
sales_channel_id,
|
||||
variants,
|
||||
items,
|
||||
},
|
||||
})
|
||||
|
||||
updateTaxLinesStep({ cart_or_cart_id: cart, force_tax_calculation: true })
|
||||
|
||||
const finalCart = useRemoteQueryStep({
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import { ConfirmVariantInventoryWorkflowInputDTO } from "@medusajs/types"
|
||||
import { MedusaError, deepFlatMap, isDefined } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { confirmInventoryStep } from "../steps"
|
||||
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
|
||||
|
||||
export const confirmVariantInventoryWorkflowId = "confirm-item-inventory"
|
||||
export const confirmVariantInventoryWorkflow = createWorkflow(
|
||||
confirmVariantInventoryWorkflowId,
|
||||
(input: WorkflowData<ConfirmVariantInventoryWorkflowInputDTO>) => {
|
||||
const confirmInventoryInput = transform({ input }, (data) => {
|
||||
const productVariantInventoryItems = new Map<string, any>()
|
||||
const priceNotFound: string[] = []
|
||||
const stockLocationIds = new Set<string>()
|
||||
const allVariants = new Map<string, any>()
|
||||
let hasSalesChannelStockLocation = false
|
||||
let hasManagedInventory = false
|
||||
|
||||
const salesChannelId = data.input.sales_channel_id
|
||||
|
||||
deepFlatMap(
|
||||
data.input,
|
||||
"variants.inventory_items.inventory.location_levels.stock_locations.sales_channels",
|
||||
({ variants, inventory_items, stock_locations, sales_channels }) => {
|
||||
if (
|
||||
!hasSalesChannelStockLocation &&
|
||||
sales_channels?.id === salesChannelId
|
||||
) {
|
||||
hasSalesChannelStockLocation = true
|
||||
}
|
||||
|
||||
if (!isDefined(variants.calculated_price)) {
|
||||
priceNotFound.push(variants.id)
|
||||
}
|
||||
|
||||
stockLocationIds.add(stock_locations.id)
|
||||
|
||||
const inventoryItemId = inventory_items.inventory_item_id
|
||||
if (!productVariantInventoryItems.has(inventoryItemId)) {
|
||||
productVariantInventoryItems.set(inventoryItemId, {
|
||||
variant_id: inventory_items.variant_id,
|
||||
inventory_item_id: inventoryItemId,
|
||||
required_quantity: inventory_items.required_quantity,
|
||||
})
|
||||
}
|
||||
|
||||
if (!allVariants.has(variants.id)) {
|
||||
if (!hasManagedInventory && variants.manage_inventory) {
|
||||
hasManagedInventory = true
|
||||
}
|
||||
|
||||
allVariants.set(variants.id, {
|
||||
id: variants.id,
|
||||
manage_inventory: variants.manage_inventory,
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (!hasManagedInventory) {
|
||||
return { items: [] }
|
||||
}
|
||||
|
||||
if (salesChannelId && !hasSalesChannelStockLocation) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Sales channel ${salesChannelId} is not associated with any stock locations.`
|
||||
)
|
||||
}
|
||||
|
||||
if (priceNotFound.length && !data.input.ignore_price_check) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variants with IDs ${priceNotFound.join(", ")} do not have a price`
|
||||
)
|
||||
}
|
||||
|
||||
const items = prepareConfirmInventoryInput({
|
||||
product_variant_inventory_items: Array.from(
|
||||
productVariantInventoryItems.values()
|
||||
),
|
||||
location_ids: Array.from(stockLocationIds),
|
||||
items: data.input.items,
|
||||
variants: Array.from(allVariants.values()),
|
||||
})
|
||||
|
||||
return { items }
|
||||
})
|
||||
|
||||
confirmInventoryStep(confirmInventoryInput)
|
||||
}
|
||||
)
|
||||
@@ -5,10 +5,8 @@ import {
|
||||
parallelize,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { useRemoteQueryStep } from "../../../common/steps/use-remote-query"
|
||||
import {
|
||||
confirmInventoryStep,
|
||||
createCartsStep,
|
||||
findOneOrAnyRegionStep,
|
||||
findOrCreateCustomerStep,
|
||||
@@ -17,8 +15,9 @@ import {
|
||||
} from "../steps"
|
||||
import { refreshCartPromotionsStep } from "../steps/refresh-cart-promotions"
|
||||
import { updateTaxLinesStep } from "../steps/update-tax-lines"
|
||||
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
|
||||
import { productVariantsFields } from "../utils/fields"
|
||||
import { prepareLineItemData } from "../utils/prepare-line-item-data"
|
||||
import { confirmVariantInventoryWorkflow } from "./confirm-variant-inventory"
|
||||
import { refreshPaymentCollectionForCartStep } from "./refresh-payment-collection"
|
||||
|
||||
// TODO: The createCartWorkflow are missing the following steps:
|
||||
@@ -59,32 +58,7 @@ export const createCartWorkflow = createWorkflow(
|
||||
|
||||
const variants = useRemoteQueryStep({
|
||||
entry_point: "variants",
|
||||
fields: [
|
||||
"id",
|
||||
"title",
|
||||
"sku",
|
||||
"manage_inventory",
|
||||
"barcode",
|
||||
"product.id",
|
||||
"product.title",
|
||||
"product.description",
|
||||
"product.subtitle",
|
||||
"product.thumbnail",
|
||||
"product.type",
|
||||
"product.collection",
|
||||
"product.handle",
|
||||
|
||||
"calculated_price.calculated_amount",
|
||||
|
||||
"inventory_items.inventory_item_id",
|
||||
"inventory_items.required_quantity",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.name",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.name",
|
||||
],
|
||||
fields: productVariantsFields,
|
||||
variables: {
|
||||
id: variantIds,
|
||||
calculated_price: {
|
||||
@@ -94,73 +68,13 @@ export const createCartWorkflow = createWorkflow(
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const confirmInventoryInput = transform(
|
||||
{ input, salesChannel, variants },
|
||||
(data) => {
|
||||
const managedVariants = data.variants.filter((v) => v.manage_inventory)
|
||||
if (!managedVariants.length) {
|
||||
return { items: [] }
|
||||
}
|
||||
|
||||
const productVariantInventoryItems: any[] = []
|
||||
|
||||
const stockLocations = managedVariants
|
||||
.map((v) => v.inventory_items)
|
||||
.flat()
|
||||
.map((ii) => {
|
||||
productVariantInventoryItems.push({
|
||||
variant_id: ii.variant_id,
|
||||
inventory_item_id: ii.inventory_item_id,
|
||||
required_quantity: ii.required_quantity,
|
||||
})
|
||||
|
||||
return ii.inventory.location_levels
|
||||
})
|
||||
.flat()
|
||||
.map((ll) => ll.stock_locations)
|
||||
.flat()
|
||||
|
||||
const salesChannelId = data.salesChannel?.id
|
||||
if (salesChannelId) {
|
||||
const salesChannels = stockLocations
|
||||
.map((sl) => sl.sales_channels)
|
||||
.flat()
|
||||
.filter((sc) => sc.id === salesChannelId)
|
||||
|
||||
if (!salesChannels.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Sales channel ${salesChannelId} is not associated with any stock locations.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const priceNotFound: string[] = data.variants
|
||||
.filter((v) => !v.calculated_price)
|
||||
.map((v) => v.id)
|
||||
|
||||
if (priceNotFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variants with IDs ${priceNotFound.join(", ")} do not have a price`
|
||||
)
|
||||
}
|
||||
|
||||
const items = prepareConfirmInventoryInput({
|
||||
product_variant_inventory_items: productVariantInventoryItems,
|
||||
location_ids: stockLocations.map((l) => l.id),
|
||||
items: data.input.items!,
|
||||
variants: data.variants.map((v) => ({
|
||||
id: v.id,
|
||||
manage_inventory: v.manage_inventory,
|
||||
})),
|
||||
})
|
||||
|
||||
return { items }
|
||||
}
|
||||
)
|
||||
|
||||
confirmInventoryStep(confirmInventoryInput)
|
||||
confirmVariantInventoryWorkflow.runAsStep({
|
||||
input: {
|
||||
sales_channel_id: salesChannel.id,
|
||||
variants,
|
||||
items: input.items!,
|
||||
},
|
||||
})
|
||||
|
||||
const priceSets = getVariantPriceSetsStep({
|
||||
variantIds,
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import {
|
||||
CartDTO,
|
||||
CreatePaymentCollectionForCartWorkflowInputDTO,
|
||||
} from "@medusajs/types"
|
||||
import { CreatePaymentCollectionForCartWorkflowInputDTO } from "@medusajs/types"
|
||||
import {
|
||||
WorkflowData,
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { retrieveCartStep } from "../steps"
|
||||
import { createPaymentCollectionsStep } from "../steps/create-payment-collection"
|
||||
import { linkCartAndPaymentCollectionsStep } from "../steps/link-cart-payment-collection"
|
||||
|
||||
@@ -17,7 +13,7 @@ export const createPaymentCollectionForCartWorkflow = createWorkflow(
|
||||
createPaymentCollectionForCartWorkflowId,
|
||||
(
|
||||
input: WorkflowData<CreatePaymentCollectionForCartWorkflowInputDTO>
|
||||
): WorkflowData<CartDTO> => {
|
||||
): WorkflowData<void> => {
|
||||
const created = createPaymentCollectionsStep([input])
|
||||
|
||||
const link = transform({ cartId: input.cart_id, created }, (data) => ({
|
||||
@@ -30,9 +26,5 @@ export const createPaymentCollectionForCartWorkflow = createWorkflow(
|
||||
}))
|
||||
|
||||
linkCartAndPaymentCollectionsStep(link)
|
||||
|
||||
const cart = retrieveCartStep({ id: input.cart_id })
|
||||
|
||||
return cart
|
||||
}
|
||||
)
|
||||
|
||||
@@ -4,13 +4,15 @@ import {
|
||||
createWorkflow,
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { useRemoteQueryStep } from "../../../common/steps/use-remote-query"
|
||||
import { updateLineItemsStep } from "../../line-item/steps"
|
||||
import { confirmInventoryStep, refreshCartShippingMethodsStep } from "../steps"
|
||||
import { refreshCartShippingMethodsStep } from "../steps"
|
||||
import { refreshCartPromotionsStep } from "../steps/refresh-cart-promotions"
|
||||
import { cartFieldsForRefreshSteps } from "../utils/fields"
|
||||
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
|
||||
import {
|
||||
cartFieldsForRefreshSteps,
|
||||
productVariantsFields,
|
||||
} from "../utils/fields"
|
||||
import { confirmVariantInventoryWorkflow } from "./confirm-variant-inventory"
|
||||
import { refreshPaymentCollectionForCartStep } from "./refresh-payment-collection"
|
||||
|
||||
// TODO: The UpdateLineItemsWorkflow are missing the following steps:
|
||||
@@ -35,32 +37,7 @@ export const updateLineItemInCartWorkflow = createWorkflow(
|
||||
|
||||
const variants = useRemoteQueryStep({
|
||||
entry_point: "variants",
|
||||
fields: [
|
||||
"id",
|
||||
"title",
|
||||
"sku",
|
||||
"barcode",
|
||||
"manage_inventory",
|
||||
"product.id",
|
||||
"product.title",
|
||||
"product.description",
|
||||
"product.subtitle",
|
||||
"product.thumbnail",
|
||||
"product.type",
|
||||
"product.collection",
|
||||
"product.handle",
|
||||
|
||||
"calculated_price.calculated_amount",
|
||||
|
||||
"inventory_items.inventory_item_id",
|
||||
"inventory_items.required_quantity",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.name",
|
||||
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.id",
|
||||
"inventory_items.inventory.location_levels.stock_locations.sales_channels.name",
|
||||
],
|
||||
fields: productVariantsFields,
|
||||
variables: {
|
||||
id: variantIds,
|
||||
calculated_price: {
|
||||
@@ -70,70 +47,17 @@ export const updateLineItemInCartWorkflow = createWorkflow(
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
const confirmInventoryInput = transform({ input, variants }, (data) => {
|
||||
const managedVariants = data.variants.filter((v) => v.manage_inventory)
|
||||
if (!managedVariants.length) {
|
||||
return { items: [] }
|
||||
}
|
||||
|
||||
const productVariantInventoryItems: any[] = []
|
||||
|
||||
const stockLocations = data.variants
|
||||
.map((v) => v.inventory_items)
|
||||
.flat()
|
||||
.map((ii) => {
|
||||
productVariantInventoryItems.push({
|
||||
variant_id: ii.variant_id,
|
||||
inventory_item_id: ii.inventory_item_id,
|
||||
required_quantity: ii.required_quantity,
|
||||
})
|
||||
|
||||
return ii.inventory.location_levels
|
||||
})
|
||||
.flat()
|
||||
.map((ll) => ll.stock_locations)
|
||||
.flat()
|
||||
|
||||
const salesChannelId = data.input.cart.sales_channel_id
|
||||
if (salesChannelId) {
|
||||
const salesChannels = stockLocations
|
||||
.map((sl) => sl.sales_channels)
|
||||
.flat()
|
||||
.filter((sc) => sc.id === salesChannelId)
|
||||
|
||||
if (!salesChannels.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Sales channel ${salesChannelId} is not associated with any stock locations.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const priceNotFound: string[] = data.variants
|
||||
.filter((v) => !v.calculated_price)
|
||||
.map((v) => v.id)
|
||||
|
||||
if (priceNotFound.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Variants with IDs ${priceNotFound.join(", ")} do not have a price`
|
||||
)
|
||||
}
|
||||
|
||||
const items = prepareConfirmInventoryInput({
|
||||
product_variant_inventory_items: productVariantInventoryItems,
|
||||
location_ids: stockLocations.map((l) => l.id),
|
||||
items: [data.input.item!],
|
||||
variants: data.variants.map((v) => ({
|
||||
id: v.id,
|
||||
manage_inventory: v.manage_inventory,
|
||||
})),
|
||||
})
|
||||
|
||||
return { items }
|
||||
const items = transform({ input }, (data) => {
|
||||
return [data.input.item]
|
||||
})
|
||||
|
||||
confirmInventoryStep(confirmInventoryInput)
|
||||
confirmVariantInventoryWorkflow.runAsStep({
|
||||
input: {
|
||||
sales_channel_id: input.cart.sales_channel_id as string,
|
||||
variants,
|
||||
items,
|
||||
},
|
||||
})
|
||||
|
||||
const lineItemUpdate = transform({ input, variants }, (data) => {
|
||||
const variant = data.variants[0]
|
||||
|
||||
@@ -122,3 +122,32 @@ export interface PricedShippingOptionDTO extends ShippingOptionDTO {
|
||||
export interface CompleteCartWorkflowInputDTO {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface ConfirmVariantInventoryWorkflowInputDTO {
|
||||
ignore_price_check?: boolean
|
||||
|
||||
sales_channel_id: string
|
||||
variants: {
|
||||
id: string
|
||||
manage_inventory: boolean
|
||||
inventory_items: {
|
||||
inventory_item_id: string
|
||||
variant_id: string
|
||||
required_quantity: BigNumberInput
|
||||
inventory: {
|
||||
location_levels: {
|
||||
stock_locations: {
|
||||
id: string
|
||||
sales_channels: {
|
||||
id: string
|
||||
}[]
|
||||
}[]
|
||||
}
|
||||
}[]
|
||||
}[]
|
||||
}[]
|
||||
items: {
|
||||
variant_id?: string
|
||||
quantity: BigNumberInput
|
||||
}[]
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import {
|
||||
WorkflowManager,
|
||||
} from "@medusajs/orchestration"
|
||||
import { LoadedModule, MedusaContainer } from "@medusajs/types"
|
||||
import { isString, OrchestrationUtils } from "@medusajs/utils"
|
||||
import { OrchestrationUtils, isString } from "@medusajs/utils"
|
||||
import { exportWorkflow } from "../../helper"
|
||||
import { createStep } from "./create-step"
|
||||
import { StepResponse } from "./helpers"
|
||||
import { proxify } from "./helpers/proxy"
|
||||
import {
|
||||
CreateWorkflowComposerContext,
|
||||
@@ -14,8 +16,6 @@ import {
|
||||
WorkflowData,
|
||||
WorkflowDataProperties,
|
||||
} from "./type"
|
||||
import { createStep } from "./create-step"
|
||||
import { StepResponse } from "./helpers"
|
||||
|
||||
global[OrchestrationUtils.SymbolMedusaWorkflowComposerContext] = null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user