chore(core-flows): util to format inventory input (#8483)
This commit is contained in:
committed by
GitHub
parent
d50161fa32
commit
0b6bcdd538
@@ -1,5 +1,8 @@
|
||||
import { BigNumberInput } from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import {
|
||||
BigNumberInput,
|
||||
ConfirmVariantInventoryWorkflowInputDTO,
|
||||
} from "@medusajs/types"
|
||||
import { MedusaError, deepFlatMap } from "@medusajs/utils"
|
||||
|
||||
interface ConfirmInventoryPreparationInput {
|
||||
product_variant_inventory_items: {
|
||||
@@ -29,7 +32,93 @@ interface ConfirmInventoryItem {
|
||||
location_ids: string[]
|
||||
}
|
||||
|
||||
export const prepareConfirmInventoryInput = ({
|
||||
export const prepareConfirmInventoryInput = (data: {
|
||||
input: ConfirmVariantInventoryWorkflowInputDTO
|
||||
}) => {
|
||||
const productVariantInventoryItems = new Map<string, any>()
|
||||
const stockLocationIds = new Set<string>()
|
||||
const allVariants = new Map<string, any>()
|
||||
let hasSalesChannelStockLocation = false
|
||||
let hasManagedInventory = false
|
||||
|
||||
const salesChannelId = data.input.sales_channel_id
|
||||
|
||||
for (const updateItem of data.input.itemsToUpdate ?? []) {
|
||||
const item = data.input.items.find(
|
||||
(item) => item.variant_id === updateItem.data.variant_id
|
||||
)
|
||||
if (item && updateItem.data.quantity) {
|
||||
item.quantity = updateItem.data.quantity!
|
||||
}
|
||||
}
|
||||
|
||||
deepFlatMap(
|
||||
data.input,
|
||||
"variants.inventory_items.inventory.location_levels.stock_locations.sales_channels",
|
||||
({ variants, inventory_items, stock_locations, sales_channels }) => {
|
||||
if (!variants) {
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
!hasSalesChannelStockLocation &&
|
||||
sales_channels?.id === salesChannelId
|
||||
) {
|
||||
hasSalesChannelStockLocation = true
|
||||
}
|
||||
|
||||
if (stock_locations) {
|
||||
stockLocationIds.add(stock_locations.id)
|
||||
}
|
||||
|
||||
if (inventory_items) {
|
||||
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 location.`
|
||||
)
|
||||
}
|
||||
|
||||
const items = formatInventoryInput({
|
||||
product_variant_inventory_items: Array.from(
|
||||
productVariantInventoryItems.values()
|
||||
),
|
||||
location_ids: Array.from(stockLocationIds),
|
||||
items: data.input.items,
|
||||
variants: Array.from(allVariants.values()),
|
||||
})
|
||||
|
||||
return { items }
|
||||
}
|
||||
|
||||
const formatInventoryInput = ({
|
||||
product_variant_inventory_items,
|
||||
location_ids,
|
||||
items,
|
||||
|
||||
@@ -17,12 +17,12 @@ import { authorizePaymentSessionStep } from "../../../payment/steps/authorize-pa
|
||||
import { validateCartPaymentsStep } from "../steps"
|
||||
import { reserveInventoryStep } from "../steps/reserve-inventory"
|
||||
import { completeCartFields } from "../utils/fields"
|
||||
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
|
||||
import {
|
||||
prepareAdjustmentsData,
|
||||
prepareLineItemData,
|
||||
prepareTaxLinesData,
|
||||
} from "../utils/prepare-line-item-data"
|
||||
import { confirmVariantInventoryWorkflow } from "./confirm-variant-inventory"
|
||||
|
||||
export const completeCartWorkflowId = "complete-cart"
|
||||
export const completeCartWorkflow = createWorkflow(
|
||||
@@ -66,14 +66,16 @@ export const completeCartWorkflow = createWorkflow(
|
||||
}
|
||||
)
|
||||
|
||||
const formatedInventoryItems = confirmVariantInventoryWorkflow.runAsStep({
|
||||
input: {
|
||||
skipInventoryCheck: true,
|
||||
sales_channel_id,
|
||||
variants,
|
||||
items,
|
||||
const formatedInventoryItems = transform(
|
||||
{
|
||||
input: {
|
||||
sales_channel_id,
|
||||
variants,
|
||||
items,
|
||||
},
|
||||
},
|
||||
})
|
||||
prepareConfirmInventoryInput
|
||||
)
|
||||
|
||||
const [, finalCart] = parallelize(
|
||||
reserveInventoryStep(formatedInventoryItems),
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { ConfirmVariantInventoryWorkflowInputDTO } from "@medusajs/types"
|
||||
import { MedusaError, deepFlatMap } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
WorkflowResponse,
|
||||
createWorkflow,
|
||||
transform,
|
||||
when,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { confirmInventoryStep } from "../steps"
|
||||
import { prepareConfirmInventoryInput } from "../utils/prepare-confirm-inventory-input"
|
||||
@@ -27,95 +25,12 @@ export const confirmVariantInventoryWorkflow = createWorkflow(
|
||||
(
|
||||
input: WorkflowData<ConfirmVariantInventoryWorkflowInputDTO>
|
||||
): WorkflowResponse<Output> => {
|
||||
const confirmInventoryInput = transform({ input }, (data) => {
|
||||
const productVariantInventoryItems = new Map<string, any>()
|
||||
const stockLocationIds = new Set<string>()
|
||||
const allVariants = new Map<string, any>()
|
||||
let hasSalesChannelStockLocation = false
|
||||
let hasManagedInventory = false
|
||||
const confirmInventoryInput = transform(
|
||||
{ input },
|
||||
prepareConfirmInventoryInput
|
||||
)
|
||||
|
||||
const salesChannelId = data.input.sales_channel_id
|
||||
|
||||
for (const updateItem of data.input.itemsToUpdate ?? []) {
|
||||
const item = data.input.items.find(
|
||||
(item) => item.variant_id === updateItem.data.variant_id
|
||||
)
|
||||
if (item && updateItem.data.quantity) {
|
||||
item.quantity = updateItem.data.quantity!
|
||||
}
|
||||
}
|
||||
|
||||
deepFlatMap(
|
||||
data.input,
|
||||
"variants.inventory_items.inventory.location_levels.stock_locations.sales_channels",
|
||||
({ variants, inventory_items, stock_locations, sales_channels }) => {
|
||||
if (!variants) {
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
!hasSalesChannelStockLocation &&
|
||||
sales_channels?.id === salesChannelId
|
||||
) {
|
||||
hasSalesChannelStockLocation = true
|
||||
}
|
||||
|
||||
if (stock_locations) {
|
||||
stockLocationIds.add(stock_locations.id)
|
||||
}
|
||||
|
||||
if (inventory_items) {
|
||||
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 location.`
|
||||
)
|
||||
}
|
||||
|
||||
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 }
|
||||
})
|
||||
|
||||
when({ input }, ({ input }) => {
|
||||
return !input.skipInventoryCheck
|
||||
}).then(() => {
|
||||
confirmInventoryStep(confirmInventoryInput)
|
||||
})
|
||||
confirmInventoryStep(confirmInventoryInput)
|
||||
|
||||
return new WorkflowResponse(confirmInventoryInput)
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { createRemoteLinkStep, useRemoteQueryStep } from "../../../common"
|
||||
import { reserveInventoryStep } from "../../../definition/cart/steps/reserve-inventory"
|
||||
import { confirmVariantInventoryWorkflow } from "../../../definition/cart/workflows/confirm-variant-inventory"
|
||||
import { prepareConfirmInventoryInput } from "../../../definition/cart/utils/prepare-confirm-inventory-input"
|
||||
import { createReturnFulfillmentWorkflow } from "../../../fulfillment/workflows/create-return-fulfillment"
|
||||
import { previewOrderChangeStep, updateReturnsStep } from "../../steps"
|
||||
import { createOrderClaimItemsFromActionsStep } from "../../steps/claim/create-claim-items-from-actions"
|
||||
@@ -310,14 +310,16 @@ export const confirmClaimRequestWorkflow = createWorkflow(
|
||||
}
|
||||
})
|
||||
|
||||
const formatedInventoryItems = confirmVariantInventoryWorkflow.runAsStep({
|
||||
input: {
|
||||
skipInventoryCheck: true,
|
||||
sales_channel_id: (claim as any).order.sales_channel_id,
|
||||
variants,
|
||||
items,
|
||||
const formatedInventoryItems = transform(
|
||||
{
|
||||
input: {
|
||||
sales_channel_id: (claim as any).order.sales_channel_id,
|
||||
variants,
|
||||
items,
|
||||
},
|
||||
},
|
||||
})
|
||||
prepareConfirmInventoryInput
|
||||
)
|
||||
|
||||
reserveInventoryStep(formatedInventoryItems)
|
||||
})
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { createRemoteLinkStep, useRemoteQueryStep } from "../../../common"
|
||||
import { reserveInventoryStep } from "../../../definition/cart/steps/reserve-inventory"
|
||||
import { confirmVariantInventoryWorkflow } from "../../../definition/cart/workflows/confirm-variant-inventory"
|
||||
import { prepareConfirmInventoryInput } from "../../../definition/cart/utils/prepare-confirm-inventory-input"
|
||||
import { createReturnFulfillmentWorkflow } from "../../../fulfillment/workflows/create-return-fulfillment"
|
||||
import { previewOrderChangeStep } from "../../steps"
|
||||
import { confirmOrderChanges } from "../../steps/confirm-order-changes"
|
||||
@@ -297,14 +297,16 @@ export const confirmExchangeRequestWorkflow = createWorkflow(
|
||||
}
|
||||
})
|
||||
|
||||
const formatedInventoryItems = confirmVariantInventoryWorkflow.runAsStep({
|
||||
input: {
|
||||
skipInventoryCheck: true,
|
||||
sales_channel_id: (exchange as any).order.sales_channel_id,
|
||||
variants,
|
||||
items,
|
||||
const formatedInventoryItems = transform(
|
||||
{
|
||||
input: {
|
||||
sales_channel_id: (exchange as any).order.sales_channel_id,
|
||||
variants,
|
||||
items,
|
||||
},
|
||||
},
|
||||
})
|
||||
prepareConfirmInventoryInput
|
||||
)
|
||||
|
||||
reserveInventoryStep(formatedInventoryItems)
|
||||
})
|
||||
|
||||
@@ -122,7 +122,6 @@ export interface CompleteCartWorkflowInputDTO {
|
||||
}
|
||||
|
||||
export interface ConfirmVariantInventoryWorkflowInputDTO {
|
||||
skipInventoryCheck?: boolean
|
||||
sales_channel_id: string
|
||||
variants: {
|
||||
id: string
|
||||
|
||||
Reference in New Issue
Block a user