feat(medusa, core-flows): add ppdate inventory item endpoint (#6735)
* init update inventory item * prep for pr
This commit is contained in:
1 parent
8155e2cfad
commit
64c2731e46
8 files changed
+249
-26
No files matched your search
@@ -89,31 +89,6 @@ medusaIntegrationTestRunner({
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it.skip("should update the inventory item", async () => {
|
|
||||||
const inventoryItemId = inventoryItems[0].id
|
|
||||||
|
|
||||||
const response = await api.post(
|
|
||||||
`/admin/inventory-items/${inventoryItemId}`,
|
|
||||||
{
|
|
||||||
mid_code: "updated mid_code",
|
|
||||||
weight: 120,
|
|
||||||
},
|
|
||||||
adminHeaders
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(response.data.inventory_item).toEqual(
|
|
||||||
expect.objectContaining({
|
|
||||||
origin_country: "UK",
|
|
||||||
hs_code: "hs001",
|
|
||||||
mid_code: "updated mid_code",
|
|
||||||
weight: 120,
|
|
||||||
length: 100,
|
|
||||||
height: 200,
|
|
||||||
width: 150,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it.skip("should fail to update the location level to negative quantity", async () => {
|
it.skip("should fail to update the location level to negative quantity", async () => {
|
||||||
const inventoryItemId = inventoryItems[0].id
|
const inventoryItemId = inventoryItems[0].id
|
||||||
|
|
||||||
@@ -229,6 +204,40 @@ medusaIntegrationTestRunner({
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("Update inventory item", () => {
|
||||||
|
let inventoryItemId
|
||||||
|
beforeEach(async () => {
|
||||||
|
const inventoryItemResponse = await api.post(
|
||||||
|
`/admin/inventory-items`,
|
||||||
|
{
|
||||||
|
sku: "test-sku",
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
inventoryItemId = inventoryItemResponse.data.inventory_item.id
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should update the inventory item", async () => {
|
||||||
|
const response = await api.post(
|
||||||
|
`/admin/inventory-items/${inventoryItemId}`,
|
||||||
|
{
|
||||||
|
mid_code: "updated mid_code",
|
||||||
|
weight: 120,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.data.inventory_item).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
sku: "test-sku",
|
||||||
|
mid_code: "updated mid_code",
|
||||||
|
weight: 120,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("Delete inventory levels", () => {
|
describe("Delete inventory levels", () => {
|
||||||
const locationId = "loc_1"
|
const locationId = "loc_1"
|
||||||
let inventoryItem
|
let inventoryItem
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ export * from "./create-inventory-items"
|
|||||||
export * from "./validate-singular-inventory-items-for-tags"
|
export * from "./validate-singular-inventory-items-for-tags"
|
||||||
export * from "./create-inventory-levels"
|
export * from "./create-inventory-levels"
|
||||||
export * from "./validate-inventory-locations"
|
export * from "./validate-inventory-locations"
|
||||||
|
export * from "./update-inventory-items"
|
||||||
export * from "./delete-inventory-levels"
|
export * from "./delete-inventory-levels"
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { IInventoryServiceNext, InventoryNext } from "@medusajs/types"
|
||||||
|
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||||
|
import {
|
||||||
|
convertItemResponseToUpdateRequest,
|
||||||
|
getSelectsAndRelationsFromObjectArray,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
|
||||||
|
export const updateInventoryItemsStepId = "update-inventory-items-step"
|
||||||
|
export const updateInventoryItemsStep = createStep(
|
||||||
|
updateInventoryItemsStepId,
|
||||||
|
async (input: InventoryNext.UpdateInventoryItemInput[], { container }) => {
|
||||||
|
const inventoryService = container.resolve<IInventoryServiceNext>(
|
||||||
|
ModuleRegistrationName.INVENTORY
|
||||||
|
)
|
||||||
|
const { selects, relations } = getSelectsAndRelationsFromObjectArray(input)
|
||||||
|
|
||||||
|
const dataBeforeUpdate = await inventoryService.list(
|
||||||
|
{ id: input.map(({ id }) => id) },
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
|
||||||
|
const updatedInventoryItems = await inventoryService.update(input)
|
||||||
|
|
||||||
|
return new StepResponse(updatedInventoryItems, {
|
||||||
|
dataBeforeUpdate,
|
||||||
|
selects,
|
||||||
|
relations,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async (revertInput, { container }) => {
|
||||||
|
if (!revertInput?.dataBeforeUpdate?.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { dataBeforeUpdate, selects, relations } = revertInput
|
||||||
|
|
||||||
|
const inventoryService = container.resolve<IInventoryServiceNext>(
|
||||||
|
ModuleRegistrationName.INVENTORY
|
||||||
|
)
|
||||||
|
|
||||||
|
await inventoryService.update(
|
||||||
|
dataBeforeUpdate.map((data) =>
|
||||||
|
convertItemResponseToUpdateRequest(data, selects, relations)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from "./delete-inventory-items"
|
export * from "./delete-inventory-items"
|
||||||
export * from "./create-inventory-items"
|
export * from "./create-inventory-items"
|
||||||
export * from "./create-inventory-levels"
|
export * from "./create-inventory-levels"
|
||||||
|
export * from "./update-inventory-items"
|
||||||
export * from "./delete-inventory-levels"
|
export * from "./delete-inventory-levels"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
|
import { InventoryNext } from "@medusajs/types"
|
||||||
|
import { updateInventoryItemsStep } from "../steps"
|
||||||
|
|
||||||
|
interface WorkflowInput {
|
||||||
|
updates: InventoryNext.UpdateInventoryItemInput[]
|
||||||
|
}
|
||||||
|
export const updateInventoryItemsWorkflowId = "update-inventory-items-workflow"
|
||||||
|
export const updateInventoryItemsWorkflow = createWorkflow(
|
||||||
|
updateInventoryItemsWorkflowId,
|
||||||
|
(
|
||||||
|
input: WorkflowData<WorkflowInput>
|
||||||
|
): WorkflowData<InventoryNext.InventoryItemDTO[]> => {
|
||||||
|
return updateInventoryItemsStep(input.updates)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -4,8 +4,12 @@ import {
|
|||||||
remoteQueryObjectFromString,
|
remoteQueryObjectFromString,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||||
|
import {
|
||||||
|
deleteInventoryItemWorkflow,
|
||||||
|
updateInventoryItemsWorkflow,
|
||||||
|
} from "@medusajs/core-flows"
|
||||||
|
|
||||||
import { deleteInventoryItemWorkflow } from "@medusajs/core-flows"
|
import { AdminPostInventoryItemsInventoryItemReq } from "../validators"
|
||||||
|
|
||||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
@@ -38,6 +42,36 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update inventory item
|
||||||
|
export const POST = async (
|
||||||
|
req: MedusaRequest<AdminPostInventoryItemsInventoryItemReq>,
|
||||||
|
res: MedusaResponse
|
||||||
|
) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
await updateInventoryItemsWorkflow(req.scope).run({
|
||||||
|
input: {
|
||||||
|
updates: [{ id, ...req.validatedBody }],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
|
||||||
|
const [inventory_item] = await remoteQuery(
|
||||||
|
remoteQueryObjectFromString({
|
||||||
|
entryPoint: "inventory",
|
||||||
|
variables: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
fields: req.retrieveConfig.select as string[],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
inventory_item,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => {
|
export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
const id = req.params.id
|
const id = req.params.id
|
||||||
const deleteInventoryItems = deleteInventoryItemWorkflow(req.scope)
|
const deleteInventoryItems = deleteInventoryItemWorkflow(req.scope)
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import * as QueryConfig from "./query-config"
|
|||||||
import {
|
import {
|
||||||
AdminGetInventoryItemsItemParams,
|
AdminGetInventoryItemsItemParams,
|
||||||
AdminGetInventoryItemsParams,
|
AdminGetInventoryItemsParams,
|
||||||
|
AdminPostInventoryItemsInventoryItemParams,
|
||||||
|
AdminPostInventoryItemsInventoryItemReq,
|
||||||
AdminPostInventoryItemsItemLocationLevelsReq,
|
AdminPostInventoryItemsItemLocationLevelsReq,
|
||||||
AdminPostInventoryItemsReq,
|
AdminPostInventoryItemsReq,
|
||||||
} from "./validators"
|
} from "./validators"
|
||||||
@@ -53,4 +55,15 @@ export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/inventory-items/:id",
|
||||||
|
middlewares: [
|
||||||
|
transformBody(AdminPostInventoryItemsInventoryItemReq),
|
||||||
|
transformQuery(
|
||||||
|
AdminPostInventoryItemsInventoryItemParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
@@ -257,3 +257,102 @@ export class AdminPostInventoryItemsReq {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
metadata?: Record<string, unknown>
|
metadata?: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @schema AdminPostInventoryItemsInventoryItemReq
|
||||||
|
* type: object
|
||||||
|
* description: "The attributes to update in an inventory item."
|
||||||
|
* properties:
|
||||||
|
* hs_code:
|
||||||
|
* description: The Harmonized System code of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
||||||
|
* type: string
|
||||||
|
* origin_country:
|
||||||
|
* description: The country in which the Inventory Item was produced. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
||||||
|
* type: string
|
||||||
|
* mid_code:
|
||||||
|
* description: The Manufacturers Identification code that identifies the manufacturer of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
||||||
|
* type: string
|
||||||
|
* material:
|
||||||
|
* description: The material and composition that the Inventory Item is made of, May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
||||||
|
* type: string
|
||||||
|
* weight:
|
||||||
|
* description: The weight of the Inventory Item. May be used in shipping rate calculations.
|
||||||
|
* type: number
|
||||||
|
* height:
|
||||||
|
* description: The height of the Inventory Item. May be used in shipping rate calculations.
|
||||||
|
* type: number
|
||||||
|
* width:
|
||||||
|
* description: The width of the Inventory Item. May be used in shipping rate calculations.
|
||||||
|
* type: number
|
||||||
|
* length:
|
||||||
|
* description: The length of the Inventory Item. May be used in shipping rate calculations.
|
||||||
|
* type: number
|
||||||
|
* title:
|
||||||
|
* description: The inventory item's title.
|
||||||
|
* type: string
|
||||||
|
* description:
|
||||||
|
* description: The inventory item's description.
|
||||||
|
* type: string
|
||||||
|
* thumbnail:
|
||||||
|
* description: The inventory item's thumbnail.
|
||||||
|
* type: string
|
||||||
|
* requires_shipping:
|
||||||
|
* description: Whether the item requires shipping.
|
||||||
|
* type: boolean
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class AdminPostInventoryItemsInventoryItemReq {
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
sku?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
origin_country?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
hs_code?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
mid_code?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
material?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
weight?: number
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
height?: number
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
length?: number
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
width?: number
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
title?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
description?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
thumbnail?: string
|
||||||
|
|
||||||
|
@IsBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
requires_shipping?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminPostInventoryItemsInventoryItemParams extends FindParams {}
|
||||||
Reference in new issue
Block a user