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