chore(core-flows,inventory,types,medusa): add fixes to inventory module + location levels api (#7629)

what:

- santizes inputs to prevent reserved_quantity from being updated directly
- inventory items create api can create location levels
- add validation to update quantity of reservation items
- general cleanup

RESOLVES CORE-2254
This commit is contained in:
Riqwan Thamir
2024-06-06 14:58:17 +02:00
committed by GitHub
parent 3fbb8aa671
commit 0507dbe027
13 changed files with 366 additions and 93 deletions
@@ -3,23 +3,83 @@ import {
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import {
attachInventoryItemToVariants,
createInventoryItemsStep,
validateInventoryItemsForCreate,
} from "../steps"
import { createInventoryItemsStep } from "../steps"
import { InventoryNext } from "@medusajs/types"
import { createInventoryLevelsWorkflow } from "./create-inventory-levels"
type LocationLevelWithoutInventory = Omit<
InventoryNext.CreateInventoryLevelInput,
"inventory_item_id"
>
interface WorkflowInput {
items: InventoryNext.CreateInventoryItemInput[]
items: (InventoryNext.CreateInventoryItemInput & {
location_levels?: LocationLevelWithoutInventory[]
})[]
}
const buildLocationLevelMapAndItemData = (data: WorkflowInput) => {
data.items = data.items ?? []
const inventoryItems: InventoryNext.CreateInventoryItemInput[] = []
// Keep an index to location levels mapping to inject the created inventory item
// id into the location levels workflow input
const locationLevelMap: Record<number, LocationLevelWithoutInventory[]> = {}
data.items.forEach(({ location_levels, ...inventoryItem }, index) => {
locationLevelMap[index] = location_levels?.length ? location_levels : []
inventoryItems.push(inventoryItem)
})
return {
locationLevelMap,
inventoryItems,
}
}
const buildInventoryLevelsInput = (data: {
locationLevelMap: Record<number, LocationLevelWithoutInventory[]>
items: InventoryNext.InventoryItemDTO[]
}) => {
const inventoryLevels: InventoryNext.CreateInventoryLevelInput[] = []
let index = 0
// The order of the input is critical to accurately create location levels for
// the right inventory item
data.items.forEach((item, index) => {
const locationLevels = data.locationLevelMap[index] || []
locationLevels.forEach((locationLevel) =>
inventoryLevels.push({
...locationLevel,
inventory_item_id: item.id,
})
)
})
return {
input: {
inventory_levels: inventoryLevels,
},
}
}
export const createInventoryItemsWorkflowId = "create-inventory-items-workflow"
export const createInventoryItemsWorkflow = createWorkflow(
createInventoryItemsWorkflowId,
(input: WorkflowData<WorkflowInput>) => {
const items = createInventoryItemsStep(input.items)
const { locationLevelMap, inventoryItems } = transform(
input,
buildLocationLevelMapAndItemData
)
const items = createInventoryItemsStep(inventoryItems)
const inventoryLevelsInput = transform(
{ items, locationLevelMap },
buildInventoryLevelsInput
)
createInventoryLevelsWorkflow.runAsStep(inventoryLevelsInput)
return items
}