docs: added multi-warehouse how-to docs (#3747)
This commit is contained in:
@@ -18,8 +18,8 @@ module.exports = {
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect"
|
||||
}
|
||||
version: "detect",
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
"no-undef": "off",
|
||||
@@ -30,8 +30,6 @@ module.exports = {
|
||||
curly: ["error", "all"],
|
||||
"new-cap": "off",
|
||||
"require-jsdoc": "off",
|
||||
"no-unused-expressions": "off",
|
||||
"no-unused-vars": "off",
|
||||
camelcase: "off",
|
||||
"no-invalid-this": "off",
|
||||
"max-len": [
|
||||
@@ -78,15 +76,15 @@ module.exports = {
|
||||
"space-infix-ops": "off",
|
||||
"eol-last": ["error", "always"],
|
||||
"react/prop-types": "off",
|
||||
"react/jsx-no-undef": "off"
|
||||
"react/jsx-no-undef": "off",
|
||||
},
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
ignorePatterns: [
|
||||
'docs/content/references/**',
|
||||
'docs/content/**/events-list.md'
|
||||
"docs/content/references/**",
|
||||
"docs/content/**/events-list.md",
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
@@ -115,6 +113,7 @@ module.exports = {
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -0,0 +1,781 @@
|
||||
---
|
||||
description: 'Learn how to manage inventory items using the admin APIs. This includes how to manage inventory items and inventory levels.'
|
||||
addHowToData: true
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# How to Manage Inventory Items
|
||||
|
||||
In this document, you’ll learn how to manage inventory items using the admin APIs.
|
||||
|
||||
## Overview
|
||||
|
||||
Using the inventory items admin REST APIs, you can manage inventory items and inventory levels in your store.
|
||||
|
||||
### Scenario
|
||||
|
||||
You want to add or use the following admin functionalities:
|
||||
|
||||
- Manage inventory items. This includes listing, creating, updating, and deleting items.
|
||||
- Manage inventory levels. This includes creating, updating, and deleting inventory levels.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Medusa Components
|
||||
|
||||
It is assumed that you already have a Medusa backend installed and set up. If not, you can follow the [quickstart guide](../../../development/backend/install.mdx) to get started.
|
||||
|
||||
### Required Module
|
||||
|
||||
This guide assumes you have the Inventory module installed on your Medusa backend. If not, you can learn how to install it using [this guide](../install-modules.md#inventory-module).
|
||||
|
||||
Furthermore, inventory levels are tied to a location ID. So, it’s recommended to use the [Stock Location module](../install-modules.md#stock-location-module) if you don’t have any location logic implemented in place.
|
||||
|
||||
### JS Client
|
||||
|
||||
This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
|
||||
|
||||
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client](../../../js-client/overview.md) installed and have [created an instance of the client](../../../js-client/overview.md#configuration).
|
||||
|
||||
### Medusa React
|
||||
|
||||
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
|
||||
|
||||
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
|
||||
|
||||
### Authenticated Admin User
|
||||
|
||||
You must be an authenticated admin user before following along with the steps in the tutorial.
|
||||
|
||||
You can learn more about [authenticating as an admin user in the API reference](/api/admin/#section/Authentication).
|
||||
|
||||
---
|
||||
|
||||
## List Inventory Items
|
||||
|
||||
You can list inventory items by sending a request to the [List Inventory Items endpoint](/api/admin#tag/Inventory-Items/operation/GetInventoryItems):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.list()
|
||||
.then(({ inventory_items }) => {
|
||||
console.log(inventory_items.length)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminInventoryItems } from "medusa-react"
|
||||
|
||||
function InventoryItems() {
|
||||
const {
|
||||
inventory_items,
|
||||
isLoading } = useAdminInventoryItems()
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading && <span>Loading...</span>}
|
||||
{inventory_items && !inventory_items.length && (
|
||||
<span>No Items</span>
|
||||
)}
|
||||
{inventory_items && inventory_items.length > 0 && (
|
||||
<ul>
|
||||
{inventory_items.map(
|
||||
(item) => (
|
||||
<li key={item.id}>{item.id}</li>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default InventoryItems
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items`, {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ inventory_items }) => {
|
||||
console.log(inventory_items.length)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X GET '<BACKEND_URL>/admin/inventory-items' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint does not require any path or query parameters. You can, however, pass path parameters to search or filter inventory items. For example, you can get inventory items in a specific location by passing the `location_id` query parameter. You can learn more about available query parameters in the [API reference](/api/admin#tag/Inventory-Items/operation/GetInventoryItems).
|
||||
|
||||
This request returns an array of inventory item objects.
|
||||
|
||||
---
|
||||
|
||||
## Create an Inventory Item
|
||||
|
||||
:::tip
|
||||
|
||||
Inventory items are automatically created when a variant is created with `manage_inventory` set to `true` or updated to enable the `manage_inventory` attribute. So, in general cases, you don’t need to create an inventory item manually.
|
||||
|
||||
:::
|
||||
|
||||
You can create an inventory item by sending a request to the [Create Inventory Item endpoint](/api/admin#tag/Inventory-Items/operation/PostInventoryItems):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.create({
|
||||
variant_id,
|
||||
})
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminCreateInventoryItem } from "medusa-react"
|
||||
|
||||
const CreateInventoryItem = () => {
|
||||
const createInventoryItem = useAdminCreateInventoryItem()
|
||||
// ...
|
||||
|
||||
const handleCreate = () => {
|
||||
createInventoryItem.mutate({
|
||||
variant_id,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default CreateInventoryItem
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
variant_id,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/inventory-items' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"variant_id": "variant_123"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires in the body parameter the `variant_id` parameter, which is the ID of the variant to create this inventory item for. You can also pass other inventory-related parameters, such as `sku`. You can learn more about other available parameters in the [API reference](/api/admin#tag/Inventory-Items/operation/PostInventoryItems).
|
||||
|
||||
This request returns the created inventory item as an object.
|
||||
|
||||
---
|
||||
|
||||
## Retrieve Inventory Item
|
||||
|
||||
You can retrieve an inventory item by sending a request to the [Get Inventory Item endpoint](/api/admin#tag/Inventory-Items/operation/GetInventoryItemsInventoryItem):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.retrieve(inventoryItemId)
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminInventoryItem } from "medusa-react"
|
||||
|
||||
function InventoryItem() {
|
||||
const {
|
||||
inventory_item,
|
||||
isLoading } = useAdminInventoryItem(inventoryItemId)
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading && <span>Loading...</span>}
|
||||
{inventory_item && (
|
||||
<span>{inventory_item.sku}</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default InventoryItem
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items/${inventoryItemId}`,
|
||||
{
|
||||
credentials: "include",
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X GET '<BACKEND_URL>/admin/inventory-items/<ITEM_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint accepts the ID of the inventory item as a path parameter. You can also path query parameters such as [expand](/api/admin#section/Expanding-Fields) and [fields](/api/admin#section/Selecting-Fields).
|
||||
|
||||
The request returns the inventory item as an object.
|
||||
|
||||
---
|
||||
|
||||
## Update Inventory Item
|
||||
|
||||
You can update an inventory item by sending a request to the [Update Inventory Item endpoint](/api/admin#tag/Inventory-Items/operation/PostInventoryItemsInventoryItem):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.update(inventoryItemId, {
|
||||
origin_country: "US",
|
||||
})
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminUpdateInventoryItem } from "medusa-react"
|
||||
|
||||
const UpdateInventoryItem = () => {
|
||||
const updateInventoryItem = useAdminUpdateInventoryItem(
|
||||
inventoryItemId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleUpdate = () => {
|
||||
updateInventoryItem.mutate({
|
||||
origin_country: "US",
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default UpdateInventoryItem
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items/${inventoryItemId}`,
|
||||
{
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
origin_country: "US",
|
||||
}),
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/inventory-items/<ITEM_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"origin_country": "US"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the inventory item’s ID as a path parameter. You can pass any of the inventory item’s attributes that you want to update in its body parameter. The example above updates the value of the `origin_country` attribute. You can learn more about available body parameters in the [API reference](/api/admin#tag/Inventory-Items/operation/PostInventoryItemsInventoryItem).
|
||||
|
||||
The request returns the updated inventory item as an object.
|
||||
|
||||
---
|
||||
|
||||
## Manage Inventory levels
|
||||
|
||||
This section shows you the different ways you can manage inventory levels. Each location level is associated with an inventory item.
|
||||
|
||||
### List inventory levels
|
||||
|
||||
You can list inventory levels of an inventory item by sending a request to the [List inventory levels endpoint](/api/admin#tag/Inventory-Items/operation/GetInventoryItemsInventoryItemLocationLevels):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.listLocationLevels(inventoryItemId)
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.location_levels)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import {
|
||||
useAdminInventoryItemLocationLevels,
|
||||
} from "medusa-react"
|
||||
|
||||
function InventoryItem() {
|
||||
const {
|
||||
inventory_item,
|
||||
isLoading,
|
||||
} = useAdminInventoryItemLocationLevels(inventoryItemId)
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading && <span>Loading...</span>}
|
||||
{inventory_item && (
|
||||
<ul>
|
||||
{inventory_item.location_levels.map((level) => (
|
||||
<span key={level.id}>{level.stocked_quantity}</span>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default InventoryItem
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items/${inventoryItemId}/location-levels`, {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.location_levels)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X GET '<BACKEND_URL>/admin/inventory-items/<ITEM_ID>/location-levels' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the ID of the inventory item as a path parameter. You can also pass [expand](/api/admin#section/Expanding-Fields) and [fields](/api/admin#section/Selecting-Fields) query parameters.
|
||||
|
||||
The request returns the inventory item as an object. In that object, the list of inventory levels are available under the property `location_levels`.
|
||||
|
||||
### Create Inventory Level
|
||||
|
||||
You can create a location level by sending a request to the [Create Inventory Level endpoint](/api/admin#tag/Inventory-Items/operation/PostInventoryItemsInventoryItemLocationLevels):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.createLocationLevel(
|
||||
inventoryItemId,
|
||||
{
|
||||
location_id,
|
||||
stocked_quantity: 10,
|
||||
}
|
||||
)
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminCreateLocationLevel } from "medusa-react"
|
||||
|
||||
const CreateLocationLevel = () => {
|
||||
const createLocationLevel = useAdminCreateLocationLevel(
|
||||
inventoryItemId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleCreate = () => {
|
||||
createLocationLevel.mutate({
|
||||
location_id,
|
||||
stocked_quantity: 10,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default CreateLocationLevel
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items/${inventoryItemId}/location-levels`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
location_id,
|
||||
stocked_quantity: 10,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/inventory-items/<ITEM_ID>/location-levels' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"location_id": "<LOCATION_ID>",
|
||||
"stocked_quantity": 10
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the inventory item ID as a path parameter. In the request body, it requires the following parameters:
|
||||
|
||||
- `location_id`: The ID of the location associated with this location level. This ID is typically available through using the stock location module.
|
||||
- `stocked_quantity`: A number indicating the item’s quantity in stock.
|
||||
|
||||
You can also pass other optional request body parameters, as explained in the [API reference](/api/admin#tag/Inventory-Items/operation/PostInventoryItemsInventoryItemLocationLevels).
|
||||
|
||||
This request returns the inventory item associated with the created location level.
|
||||
|
||||
### Update Location Level
|
||||
|
||||
You can update a location level by sending a request to the [Update Location Level endpoint](/api/admin#tag/Inventory-Items/operation/PostInventoryItemsInventoryItemLocationLevelsLocationLevel):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.updateLocationLevel(
|
||||
inventoryItemId,
|
||||
locationId,
|
||||
{
|
||||
stocked_quantity: 15,
|
||||
}
|
||||
)
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminUpdateLocationLevel } from "medusa-react"
|
||||
|
||||
const UpdateLocationLevel = () => {
|
||||
const updateLocationLevel = useAdminUpdateLocationLevel(
|
||||
inventoryItemId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleUpdate = () => {
|
||||
updateLocationLevel.mutate({
|
||||
stockLocationId,
|
||||
stocked_quantity: 10,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default UpdateLocationLevel
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
stocked_quantity: 10,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/inventory-items/<ITEM_ID>/location-levels/<LOCATION_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"stocked_quantity": 10
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires two path parameters: the first one being the ID of the inventory item, and the second one being the ID of the location.
|
||||
|
||||
In the body, you can optionally pass any of the location level’s attributes to update. In the example above, you update the `stocked_quantity` attribute of the location level.
|
||||
|
||||
The request returns the inventory item associated with the location level as an object.
|
||||
|
||||
### Delete Location Level
|
||||
|
||||
You can delete a location level of an inventory item by sending a request to the [Delete Location Level endpoint](/api/admin#tag/Inventory-Items/operation/DeleteInventoryItemsInventoryIteLocationLevelsLocation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.deleteLocationLevel(
|
||||
inventoryItemId,
|
||||
locationId
|
||||
)
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminDeleteLocationLevel } from "medusa-react"
|
||||
|
||||
const DeleteLocationLevel = () => {
|
||||
const deleteLocationLevel = useAdminDeleteLocationLevel(
|
||||
inventoryItemId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleDelete = () => {
|
||||
deleteLocationLevel.mutate(locationId)
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default DeleteLocationLevel
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`, {
|
||||
credentials: "include",
|
||||
method: "DELETE",
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ inventory_item }) => {
|
||||
console.log(inventory_item.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X DELETE '<BACKEND_URL>/admin/inventory-items/<ITEM_ID>/location-levels/<LOC_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires two path parameters: the first one being the inventory item’s ID and the second one being the location level’s ID.
|
||||
|
||||
The request returns the inventory item as an object.
|
||||
|
||||
---
|
||||
|
||||
## Delete Inventory Item
|
||||
|
||||
You can delete an inventory item by sending a request to the [Delete Inventory Item endpoint](/api/admin#tag/Inventory-Items/operation/DeleteInventoryItemsInventoryItem):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.inventoryItems.delete(inventoryItemId)
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminDeleteInventoryItem } from "medusa-react"
|
||||
|
||||
const DeleteInventoryItem = () => {
|
||||
const deleteInventoryItem = useAdminDeleteInventoryItem(
|
||||
inventoryItemId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleDelete = () => {
|
||||
deleteInventoryItem.mutate()
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default DeleteInventoryItem
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/inventory-items/${inventoryItemId}`,
|
||||
{
|
||||
credentials: "include",
|
||||
method: "DELETE",
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X DELETE '<BACKEND_URL>/admin/inventory-items/<ITEM_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the inventory item’s ID be passed as a path parameter.
|
||||
|
||||
It returns the following fields in the response:
|
||||
|
||||
- `id`: The ID of the inventory item.
|
||||
- `object`: The type of object that was deleted. In this case, the value will be `inventory_item`.
|
||||
- `deleted`: A boolean value indicating whether the inventory item was deleted successfully.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [How to manage stock locations](./manage-stock-locations.mdx)
|
||||
- [How to manage item allocations in orders](./manage-item-allocations-in-orders.mdx)
|
||||
@@ -0,0 +1,689 @@
|
||||
---
|
||||
description: 'Learn how to manage item allocations in orders using the admin APIs. This includes how to manage reservations and specify a location for fulfillments and returns.'
|
||||
addHowToData: true
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# How to Manage Item Allocations in Orders
|
||||
|
||||
In this document, you’ll learn how to manage item allocations in orders using the admin APIs.
|
||||
|
||||
:::note
|
||||
|
||||
The terms “item allocation” and “reservation” are synonymous and are used interchangeably throughout this guide.
|
||||
|
||||
:::
|
||||
|
||||
## Overview
|
||||
|
||||
When an order is placed, the ordered quantity is reserved from the stocked quantity of each product variant having `manage_inventory` enabled. The reserved quantity is allocated to a random location associated with the order’s sales channel, but can also be changed afterward.
|
||||
|
||||
When a fulfillment is created, a location can be specified to fulfill the item from. This will deduct the stocked quantity and reset the reserved quantity in the chosen location based on the quantity chosen for fulfillment.
|
||||
|
||||
When a return is requested, a location can be specified to return the item to. The will increment the stocked quantity in the chosen location based on the returned quantity.
|
||||
|
||||

|
||||
|
||||
### Scenario
|
||||
|
||||
You want to add or use the following admin functionalities:
|
||||
|
||||
- Manage an item allocation for any resource, and not just for an item in an order. This includes listing, updating, or deleting item allocation.
|
||||
- Specify location when creating fulfillment.
|
||||
- Specify location when creating a return. This also applies to returns that are part of a swap or a claim.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Medusa Components
|
||||
|
||||
It is assumed that you already have a Medusa backend installed and set up. If not, you can follow the [quickstart guide](../../../development/backend/install.mdx) to get started.
|
||||
|
||||
### Required Module
|
||||
|
||||
This guide assumes you have a stock location and inventory modules installed. You can use Medusa’s [Stock Location and Inventory modules](../install-modules.md) or create your own modules.
|
||||
|
||||
### JS Client
|
||||
|
||||
This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
|
||||
|
||||
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client](../../../js-client/overview.md) installed and have [created an instance of the client](../../../js-client/overview.md#configuration).
|
||||
|
||||
### Medusa React
|
||||
|
||||
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
|
||||
|
||||
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
|
||||
|
||||
### Authenticated Admin User
|
||||
|
||||
You must be an authenticated admin user before following along with the steps in the tutorial.
|
||||
|
||||
You can learn more about [authenticating as an admin user in the API reference](/api/admin/#section/Authentication).
|
||||
|
||||
---
|
||||
|
||||
## Manage Item Allocations in an Order
|
||||
|
||||
Using the reservations admin REST APIs, you can create an item allocation or reservation for any resource, and not just items in an order. This gives you more options in how you handle item allocations.
|
||||
|
||||
In this guide, however, the focus will be on how to use these endpoints for order-related functionalities.
|
||||
|
||||
### Create Item Allocation
|
||||
|
||||
Item allocations are created automatically for items that are associated with product variants having the `manage_inventory` attribute enabled. You typically don’t need to create an item allocation, unless you delete the previous item allocation.
|
||||
|
||||
You can create an item allocation by sending a request to the [Create a Reservation endpoint](/api/admin#tag/Reservations/operation/PostReservations):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.reservations.create({
|
||||
line_item_id,
|
||||
location_id,
|
||||
inventory_item_id,
|
||||
quantity,
|
||||
})
|
||||
.then(({ reservation }) => {
|
||||
console.log(reservation.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminCreateReservation } from "medusa-react"
|
||||
|
||||
const CreateReservation = () => {
|
||||
const createReservation = useAdminCreateReservation()
|
||||
// ...
|
||||
|
||||
const handleCreate = () => {
|
||||
createReservation.mutate({
|
||||
line_item_id,
|
||||
location_id,
|
||||
inventory_item_id,
|
||||
quantity,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default CreateReservation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/reservations`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
line_item_id,
|
||||
location_id,
|
||||
inventory_item_id,
|
||||
quantity,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ reservation }) => {
|
||||
console.log(reservation.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/reservations' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"line_item_id": "<LINE_ITEM_ID>",
|
||||
"location_id": "<LOC_ID>",
|
||||
"inventory_item_id": "<INV_ITEM_ID>",
|
||||
"quantity": 1
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the following body parameters:
|
||||
|
||||
- `line_item_id`: The ID of the order’s line item the allocation is being created for.
|
||||
- `location_id`: The ID of the location the item is being allocated from.
|
||||
- `inventory_item_id`: The ID of the inventory item the line item’s variant is associated with.
|
||||
- `quantity`: The quantity to allocate.
|
||||
|
||||
The request returns the created reservation as an object.
|
||||
|
||||
### List Item Allocations
|
||||
|
||||
When listing item allocations, by default, you’ll be retrieving all item allocations in your commerce system. You can, however, provide optional fields to filter the item allocations retrieved.
|
||||
|
||||
You can retrieve the item allocations of a line item in an order using the [List Reservations endpoint](/api/admin#tag/Reservations/operation/GetReservations):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.reservations.list({
|
||||
line_item_id,
|
||||
})
|
||||
.then(({ reservations, count, limit, offset }) => {
|
||||
console.log(reservations.length)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminReservations } from "medusa-react"
|
||||
|
||||
function Reservations() {
|
||||
const { reservations, isLoading } = useAdminReservations({
|
||||
line_item_id,
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading && <span>Loading...</span>}
|
||||
{reservations && !reservations.length && (
|
||||
<span>No Reservations</span>
|
||||
)}
|
||||
{reservations && reservations.length > 0 && (
|
||||
<ul>
|
||||
{reservations.map((reservation) => (
|
||||
<li key={reservation.id}>{reservation.quantity}</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Reservations
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/reservations?line_item_id=${lineItemId}`, {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ reservations, count, limit, offset }) => {
|
||||
console.log(reservations.length)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X GET '<BACKEND_URL>/admin/reservations?line_item_id=<LINE_ITEM_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint does not require any path or query parameters. As mentioned earlier, you can pass query parameters to filter the reservations. In the code snippets above, you filter the reservations by a line item ID. You can, however, filter by other attributes, such as the ID of the location. You can refer to the [API reference](/api/admin#tag/Reservations/operation/GetReservations) for a full list of query parameters.
|
||||
|
||||
The request returns the reservations along with [pagination fields](/api/admin#section/Pagination).
|
||||
|
||||
### Retrieve Item Allocation
|
||||
|
||||
You can retrieve a single item allocation by its ID using the [Get a Reservation endpoint](/api/admin#tag/Reservations/operation/GetReservationsReservation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.reservations.retrieve(reservationId)
|
||||
.then(({ reservation }) => {
|
||||
console.log(reservation.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminReservation } from "medusa-react"
|
||||
|
||||
function Reservation() {
|
||||
const {
|
||||
reservation,
|
||||
isLoading } = useAdminReservation(reservationId)
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading && <span>Loading...</span>}
|
||||
{reservation && (
|
||||
<span>{reservation.quantity}</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Reservation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/reservations/${reservationId}`, {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ reservation }) => {
|
||||
console.log(reservation.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X GET '<BACKEND_URL>/admin/reservations/<RESERVATION_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the reservation’s ID as a path parameter.
|
||||
|
||||
The request returns the reservation as an object.
|
||||
|
||||
### Update Item Allocation
|
||||
|
||||
You can update an item allocation to change the location to allocate from or the quantity to allocate by sending a request to the [Update Reservation endpoint](/api/admin#tag/Reservations/operation/PostReservationsReservation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.reservations.update(reservationId, {
|
||||
quantity,
|
||||
})
|
||||
.then(({ reservation }) => {
|
||||
console.log(reservation.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminUpdateReservation } from "medusa-react"
|
||||
|
||||
const UpdateReservation = () => {
|
||||
const updateReservation = useAdminUpdateReservation(
|
||||
reservationId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleCreate = () => {
|
||||
updateReservation.mutate({
|
||||
quantity,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default UpdateReservation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/reservations/${reservationId}`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
quantity,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ reservation }) => {
|
||||
console.log(reservation.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/reservations/<RESERVATION_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"quantity": 3
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the ID of the reservation as a path parameter.
|
||||
|
||||
In the request body parameters, you can optionally pass any of the following parameters to make updates to the reservation:
|
||||
|
||||
- `quantity`: The quantity that should be reserved.
|
||||
- `location_id`: The ID of the location that the item should be allocated from.
|
||||
- `metadata`: set or change the reservation’s metadata.
|
||||
|
||||
The request returns the updated reservation as an object.
|
||||
|
||||
### Delete Item Allocation
|
||||
|
||||
Deleting an item allocation means that the quantity that was previously reserved is no longer reserved.
|
||||
|
||||
You can delete an item allocation by sending a request to the [Delete Reservation endpoint](/api/admin#tag/Reservations/operation/DeleteReservationsReservation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.reservations.delete(reservationId)
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminDeleteReservation } from "medusa-react"
|
||||
|
||||
const DeleteReservation = () => {
|
||||
const deleteReservation = useAdminDeleteReservation(
|
||||
reservationId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleDelete = () => {
|
||||
deleteReservation.mutate()
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default DeleteReservation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/reservations/${reservationId}`, {
|
||||
credentials: "include",
|
||||
method: "DELETE",
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X DELETE '<BACKEND_URL>/admin/reservations/<RESERVATION_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the reservation ID to be passed as a path parameter.
|
||||
|
||||
The request returns the following fields:
|
||||
|
||||
- `id`: The ID of the reservation.
|
||||
- `object`: The type of object that was removed. In this case, the value will be `reservation`.
|
||||
- `deleted`: A boolean value indicating whether the reservation was successfully deleted.
|
||||
|
||||
---
|
||||
|
||||
## Specify Location when Creating Fulfillment
|
||||
|
||||
When you create a fulfillment of an order, you can specify the location to fulfill the item from by passing the `location_id` parameter:
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.orders.createFulfillment(orderId, {
|
||||
items: [
|
||||
{
|
||||
item_id,
|
||||
quantity,
|
||||
},
|
||||
],
|
||||
// ...other parameters
|
||||
location_id,
|
||||
})
|
||||
.then(({ order }) => {
|
||||
console.log(order.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminCreateFulfillment } from "medusa-react"
|
||||
|
||||
const CreateFulfillment = () => {
|
||||
const createFulfillment = useAdminCreateFulfillment(orderId)
|
||||
// ...
|
||||
|
||||
const handleCreate = () => {
|
||||
createFulfillment.mutate({
|
||||
items: [
|
||||
{
|
||||
item_id,
|
||||
quantity,
|
||||
},
|
||||
],
|
||||
// ...other parameters
|
||||
location_id,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default CreateFulfillment
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/orders/${orderId}/fulfillment`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
items: [
|
||||
{
|
||||
item_id,
|
||||
quantity,
|
||||
},
|
||||
],
|
||||
// ...other parameters
|
||||
location_id,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ order }) => {
|
||||
console.log(order.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/orders/<ORDER_ID>/fulfillment' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"items": [
|
||||
{
|
||||
"item_id": "<LINE_ITEM_ID>",
|
||||
"quantity": 1
|
||||
}
|
||||
],
|
||||
"location_id": "<LOC_ID>"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The `location_id` is an optional parameter that allows you to specify where to fulfill the item from. This subsequently decrements the stock quantity of the product variant in that location.
|
||||
|
||||
You can learn more about this endpoint’s parameters and response in the [API reference](/api/admin#tag/Orders/operation/PostOrdersOrderFulfillments).
|
||||
|
||||
---
|
||||
|
||||
## Specify Location when Requesting Return
|
||||
|
||||
When requesting a return, you can specify the location to return the item to by passing the `location_id` parameter:
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.orders.requestReturn(orderId, {
|
||||
items: [
|
||||
{
|
||||
item_id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
// other parameters...
|
||||
location_id,
|
||||
})
|
||||
.then(({ order }) => {
|
||||
console.log(order.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminRequestReturn } from "medusa-react"
|
||||
|
||||
const RequestReturn = () => {
|
||||
const requestReturn = useAdminRequestReturn(orderId)
|
||||
// ...
|
||||
|
||||
const handleRequest = () => {
|
||||
requestReturn.mutate({
|
||||
items: [
|
||||
{
|
||||
item_id,
|
||||
quantity,
|
||||
},
|
||||
],
|
||||
// ...other parameters
|
||||
location_id,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default RequestReturn
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/orders/${orderId}/return`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
items: [
|
||||
{
|
||||
item_id,
|
||||
quantity,
|
||||
},
|
||||
],
|
||||
// ...other parameters
|
||||
location_id,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ order }) => {
|
||||
console.log(order.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/orders/<ORDER_ID>/return' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"items": [
|
||||
{
|
||||
"item_id": "<LINE_ITEM_ID>",
|
||||
"quantity": 1
|
||||
}
|
||||
],
|
||||
"location_id": "<LOC_ID>"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The `location_id` is an optional parameter that allows you to specify where to return the item to. This subsequently increments the stock quantity of the product variant in that location.
|
||||
|
||||
You can learn more about this endpoint’s parameters and response in [the API reference](/api/admin#tag/Orders/operation/PostOrdersOrderReturns).
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [How to manage inventory items](./manage-inventory-items.mdx)
|
||||
- [How to manage stock locations](./manage-stock-locations.mdx)
|
||||
@@ -0,0 +1,620 @@
|
||||
---
|
||||
description: 'Learn how to manage stock locations using the admin APIs. This includes how to list, create, update, and delete stock locations.'
|
||||
addHowToData: true
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# How to Manage Stock Locations
|
||||
|
||||
In this document, you’ll learn how to manage stock locations using the admin APIs.
|
||||
|
||||
## Overview
|
||||
|
||||
Using the stock locations admin REST APIs, you can manage stock locations in your store, including creating, updating, and deleting locations.
|
||||
|
||||
### Scenario
|
||||
|
||||
You want to add or use the following admin functionalities:
|
||||
|
||||
- List stock locations.
|
||||
- Create a stock location.
|
||||
- Retrieve a stock location.
|
||||
- Associate a stock location with a sales channel, and remove the association.
|
||||
- Update a stock location.
|
||||
- Delete a stock location.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Medusa Components
|
||||
|
||||
It is assumed that you already have a Medusa backend installed and set up. If not, you can follow the [quickstart guide](../../../development/backend/install.mdx) to get started.
|
||||
|
||||
### Required Module
|
||||
|
||||
This guide assumes you have a stock location module installed. You can use Medusa’s [Stock Location module](../install-modules.md#stock-location-module) or [create your own module](../backend/create-stock-location-service.md).
|
||||
|
||||
### JS Client
|
||||
|
||||
This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
|
||||
|
||||
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client](../../../js-client/overview.md) installed and have [created an instance of the client](../../../js-client/overview.md#configuration).
|
||||
|
||||
### Medusa React
|
||||
|
||||
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
|
||||
|
||||
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
|
||||
|
||||
### Authenticated Admin User
|
||||
|
||||
You must be an authenticated admin user before following along with the steps in the tutorial.
|
||||
|
||||
You can learn more about [authenticating as an admin user in the API reference](/api/admin/#section/Authentication).
|
||||
|
||||
---
|
||||
|
||||
## List Stock Locations
|
||||
|
||||
You can list stock locations by using the [List Stock Locations endpoint](/api/admin#tag/Stock-Locations/operation/GetStockLocations):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.stockLocations.list()
|
||||
.then(({ stock_locations, limit, offset, count }) => {
|
||||
console.log(stock_locations.length)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminStockLocations } from "medusa-react"
|
||||
|
||||
function StockLocations() {
|
||||
const {
|
||||
stock_locations,
|
||||
isLoading } = useAdminStockLocations()
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading && <span>Loading...</span>}
|
||||
{stock_locations && !stock_locations.length && (
|
||||
<span>No Locations</span>
|
||||
)}
|
||||
{stock_locations && stock_locations.length > 0 && (
|
||||
<ul>
|
||||
{stock_locations.map(
|
||||
(location) => (
|
||||
<li key={location.id}>{location.name}</li>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default StockLocations
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/stock-locations`, {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ stock_locations, limit, offset, count }) => {
|
||||
console.log(stock_locations.length)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X GET '<BACKEND_URL>/admin/stock-locations' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint does not require any path or query parameters. You can, however, pass it query parameters to search or filter the list of stock locations. For example, you can pass the `q` query parameter to search through the locations by name. You can learn about available query parameters in the [API reference](/api/admin#tag/Stock-Locations/operation/GetStockLocations).
|
||||
|
||||
The request returns an array of stock location objects along with [pagination parameters](/api/admin#section/Pagination).
|
||||
|
||||
---
|
||||
|
||||
## Create a Stock Location
|
||||
|
||||
You can create a stock location using the [Create a Stock Location endpoint](/api/admin#tag/Stock-Locations/operation/PostStockLocations):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.stockLocations.create({
|
||||
name: "Main Warehouse",
|
||||
})
|
||||
.then(({ stock_location }) => {
|
||||
console.log(stock_location.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminCreateStockLocation } from "medusa-react"
|
||||
|
||||
const CreateStockLocation = () => {
|
||||
const createStockLocation = useAdminCreateStockLocation()
|
||||
// ...
|
||||
|
||||
const handleCreate = () => {
|
||||
createStockLocation.mutate({
|
||||
name: "Main Warehouse",
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default CreateStockLocation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/stock-locations`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: "Main Warehouse",
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ stock_location }) => {
|
||||
console.log(stock_location.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/stock-locations' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"name": "Main Warehouse"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires in its body parameters the `name` field, which is the name of the stock location. You can also pass in the request body parameters other fields related to the address or metadata. You can learn more in the [API reference](/api/admin#tag/Stock-Locations/operation/PostStockLocations).
|
||||
|
||||
This request returns the created stock location as an object.
|
||||
|
||||
---
|
||||
|
||||
## Retrieve a Stock Location
|
||||
|
||||
You can retrieve a stock location by sending a request to the [Get Stock Location endpoint](/api/admin#tag/Stock-Locations/operation/GetStockLocationsStockLocation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.stockLocations.retrieve(stockLocationId)
|
||||
.then(({ stock_location }) => {
|
||||
console.log(stock_location.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminStockLocation } from "medusa-react"
|
||||
|
||||
function StockLocation() {
|
||||
const {
|
||||
stock_location,
|
||||
isLoading } = useAdminStockLocation(stockLocationId)
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading && <span>Loading...</span>}
|
||||
{stock_location && (
|
||||
<span>{stock_location.name}</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default StockLocation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/stock-locations/${stockLocationId}`,
|
||||
{
|
||||
credentials: "include",
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then(({ stock_location }) => {
|
||||
console.log(stock_location.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X GET '<BACKEND_URL>/admin/stock-locations/<LOC_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the stock location ID to be passed as a path parameter. It also accepts query parameters related to expanding and selecting fields. You can learn more in the [API reference](/api/admin#tag/Stock-Locations/operation/GetStockLocationsStockLocation).
|
||||
|
||||
It returns the stock location as an object.
|
||||
|
||||
---
|
||||
|
||||
## Associate a Stock Location with a Sales Channel
|
||||
|
||||
You can associate a stock location with a sales channel by sending a request to the [Associate Stock Channel endpoint](/api/admin#tag/Sales-Channels/operation/PostSalesChannelsSalesChannelStockLocation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.salesChannels.addLocation(salesChannelId, {
|
||||
location_id,
|
||||
})
|
||||
.then(({ sales_channel }) => {
|
||||
console.log(sales_channel.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminAddLocationToSalesChannel } from "medusa-react"
|
||||
|
||||
function StockLocation() {
|
||||
const addLocation = useAdminAddLocationToSalesChannel()
|
||||
// ...
|
||||
|
||||
const handleAdd = () => {
|
||||
addLocation.mutate({
|
||||
sales_channel_id,
|
||||
location_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default StockLocation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/sales-channels/${salesChannelId}/stock-locations`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
location_id,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ sales_channel }) => {
|
||||
console.log(sales_channel.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/sales-channels/<CHANNEL_ID>/stock-locations' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"location_id": "<LOC_ID>"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the ID of the sales channel as a path parameter. In its body parameters, it requires the ID of the stock location you’re associating the sales channel with.
|
||||
|
||||
This request returns the sales channel object.
|
||||
|
||||
:::note
|
||||
|
||||
You can associate a location with more than one sales channel, and you can associate a sales channel with more than one location.
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Remove Association Between Stock Location and Sales Channel
|
||||
|
||||
You can remove the association between a stock location and a sales channel by sending a request to the [Remove Stock Location Association endpoint](/api/admin#tag/Sales-Channels/operation/DeleteSalesChannelsSalesChannelStockLocation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.salesChannels.removeLocation(salesChannelId, {
|
||||
location_id,
|
||||
})
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import {
|
||||
useAdminRemoveLocationFromSalesChannel,
|
||||
} from "medusa-react"
|
||||
|
||||
function StockLocation() {
|
||||
const removeLocation =
|
||||
useAdminRemoveLocationFromSalesChannel()
|
||||
// ...
|
||||
|
||||
const handleRemove = () => {
|
||||
removeLocation.mutate({
|
||||
sales_channel_id,
|
||||
location_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default StockLocation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/sales-channels/${salesChannelId}/stock-locations`, {
|
||||
credentials: "include",
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
location_id,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X DELETE '<BACKEND_URL>/admin/sales-channels/<CHANNEL_ID>/stock-locations' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"location_id": "<LOC_ID>"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the ID of the sales channel as a path parameter. In its body parameters, it requires the ID of the stock location you’re removing the association of the sales channel with.
|
||||
|
||||
The request returns the following fields:
|
||||
|
||||
- `id`: The ID of the location.
|
||||
- `object`: The type of object that was removed. In this case, the value will be `stock-location`.
|
||||
- `deleted`: A boolean value indicating whether the association with the stock location was removed.
|
||||
|
||||
:::note
|
||||
|
||||
This request does not delete the stock location. It only removes the association between it and the specified sales channel.
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Update a Stock Location
|
||||
|
||||
You can update a stock location by sending a request to the [Update Stock Location endpoint](/api/admin#tag/Stock-Locations/operation/PostStockLocationsStockLocation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.stockLocations.update(stockLocationId, {
|
||||
name: "Warehouse",
|
||||
})
|
||||
.then(({ stock_location }) => {
|
||||
console.log(stock_location.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminUpdateStockLocation } from "medusa-react"
|
||||
|
||||
function StockLocation() {
|
||||
const updateLocation = useAdminUpdateStockLocation(
|
||||
stockLocationId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleRemove = () => {
|
||||
updateLocation.mutate({
|
||||
name: "Warehouse",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default StockLocation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/stock-locations/${stockLocationId}`,
|
||||
{
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: "Warehouse",
|
||||
}),
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then(({ stock_location }) => {
|
||||
console.log(stock_location.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/stock-locations/<LOC_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"name": "Main Warehouse"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the ID of a stock location as a path parameter. In its body parameters, you can pass any of the location’s attributes to update, such as the name or address. You can learn more in the [API reference](/api/admin#tag/Stock-Locations/operation/PostStockLocationsStockLocation).
|
||||
|
||||
This request returns the updated stock location as an object.
|
||||
|
||||
---
|
||||
|
||||
## Delete a Stock Location
|
||||
|
||||
You can delete a stock location by sending a request to the [Delete Stock Location endpoint](/api/admin#tag/Stock-Locations/operation/DeleteStockLocationsStockLocation):
|
||||
|
||||
<Tabs groupId="request-type" wrapperClassName="code-tabs">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.stockLocations.delete(stockLocationId)
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminDeleteStockLocation } from "medusa-react"
|
||||
|
||||
function StockLocation() {
|
||||
const deleteLocation = useAdminDeleteStockLocation(
|
||||
stockLocationId
|
||||
)
|
||||
// ...
|
||||
|
||||
const handleDelete = () => {
|
||||
deleteLocation.mutate()
|
||||
}
|
||||
}
|
||||
|
||||
export default StockLocation
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/stock-locations/${stockLocationId}`,
|
||||
{
|
||||
credentials: "include",
|
||||
method: "DELETE",
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X DELETE '<BACKEND_URL>/admin/stock-locations/<LOC_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the ID of the stock location as a path parameter.
|
||||
|
||||
It returns the following fields in the response:
|
||||
|
||||
- `id`: The ID of the location.
|
||||
- `object`: The type of object that was deleted. In this case, the value will be `stock_location`.
|
||||
- `deleted`: A boolean value indicating whether the stock location was deleted successfully.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [How to manage inventory items](./manage-inventory-items.mdx)
|
||||
- [How to manage item allocations in orders](./manage-item-allocations-in-orders.mdx)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,384 @@
|
||||
---
|
||||
description: 'Learn how to create a stock location service, which you can use in a custom stock location module in the Medusa backend.'
|
||||
addHowToData: true
|
||||
---
|
||||
|
||||
# How to Create a Stock Location Service
|
||||
|
||||
In this document, you’ll learn how to create a stock location service, which you can use in a custom stock location module in the Medusa backend.
|
||||
|
||||
## Overview
|
||||
|
||||
A stock location module is used in a commerce application, such as the Medusa backend, to handle functionalities related to the different locations a stock-kept item can be located in.
|
||||
|
||||
While Medusa provides a [stock-location module](../stock-location-module.md) that you can use in your Medusa backend, you can also create a custom module to handle these functionalities.
|
||||
|
||||
The module is expected to, at the very least, export the stock-location service. If necessary, you can include entities, migrations, and other resources as part of the export.
|
||||
|
||||
This guide will only explain what is required to create in your custom stock location service, and not the entities or other resources, as those you have the freedom to choose how to implement. You can refer to the [Modules documentation](../../../development/modules/create.mdx) for other details on how to create and use the module.
|
||||
|
||||
:::note
|
||||
|
||||
It should be noted that the Medusa backend expects the stock location module to have entities for a location and a location address, as it uses the IDs of those entities when orchestrating between different modules and the in the endpoints it exposes. You can learn more about this in the [Stock Location Module Architecture documentation](../stock-location-module.md).
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The `IStockLocationService` interface that you’ll be implementing is available in the `@medusajs/types` package. So, make sure to install it in your Medusa backend or the module project (depending on where you’re adding your implementation):
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @medusajs/types
|
||||
```
|
||||
|
||||
You’ll also be using decorators in your methods that are imported from the `@medusajs/utils` package, so make sure to install it as well:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @medusajs/utils
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Implement the Stock Location Service
|
||||
|
||||
Create a file in the `src/services` directory that will hold your custom stock location service. For example, `src/services/stock-location.ts`.
|
||||
|
||||
In that file, add the following content:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
import {
|
||||
CreateStockLocationInput,
|
||||
FilterableStockLocationProps,
|
||||
FindConfig,
|
||||
IStockLocationService,
|
||||
SharedContext,
|
||||
StockLocationDTO,
|
||||
UpdateStockLocationInput,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
InjectEntityManager,
|
||||
MedusaContext,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
class StockLocationService implements IStockLocationService {
|
||||
async list(
|
||||
selector: FilterableStockLocationProps,
|
||||
config?: FindConfig<StockLocationDTO> | undefined,
|
||||
context?: SharedContext | undefined
|
||||
): Promise<StockLocationDTO[]> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
async listAndCount(
|
||||
selector: FilterableStockLocationProps,
|
||||
config?: FindConfig<StockLocationDTO> | undefined,
|
||||
context?: SharedContext | undefined
|
||||
): Promise<[StockLocationDTO[], number]> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
async retrieve(
|
||||
id: string,
|
||||
config?: FindConfig<StockLocationDTO> | undefined,
|
||||
context?: SharedContext | undefined
|
||||
): Promise<StockLocationDTO> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
async create(
|
||||
input: CreateStockLocationInput,
|
||||
context?: SharedContext | undefined
|
||||
): Promise<StockLocationDTO> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
async update(
|
||||
id: string,
|
||||
input: UpdateStockLocationInput,
|
||||
context?: SharedContext | undefined
|
||||
): Promise<StockLocationDTO> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
async delete(
|
||||
id: string,
|
||||
context?: SharedContext | undefined
|
||||
): Promise<void> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
}
|
||||
|
||||
export default StockLocationService
|
||||
```
|
||||
|
||||
This defines the class `StockLocationService` that implements the `IStockLocationService` service imported from the `@medusajs/types` package.
|
||||
|
||||
The following sections explain the different methods you need to implement.
|
||||
|
||||
### Using Method Decorators
|
||||
|
||||
For each of the methods, you’ll be using the following decorators:
|
||||
|
||||
1. `@InjectEntityManager`: Ensures that a transaction entity manager is always passed to the method. The transaction manager is useful when performing database operations.
|
||||
2. `@MedusaContext`: Used on a parameter passed to a method having the `@InjectEntityManager` decorator. It indicates which parameter should include the injected transaction manager. When used on a `context` parameter as shown below, the context is no longer optional and you can always expect the transaction manager to be passed as a parameter.
|
||||
|
||||
To use these decorators, it’s recommended to include the following configurations in your `tsconfig.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
//other configurations
|
||||
"compilerOptions": {
|
||||
// other configurations
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Implementing list Method
|
||||
|
||||
The `list` method is used to retrieve a list of stock locations. It accepts the following parameters:
|
||||
|
||||
1. `selector`: This is the first parameter passed to the method, and the only required parameter. It is an object that has the following properties:
|
||||
1. `id`: an optional string or array of strings indicating the IDs of locations. It is used to filter the retrieved locations by ID.
|
||||
2. `name`: an optional string, array of strings, or a `StringComparisonOperator` object that is used to search and filter locations by their name. The `StringComparisonOperator` can have the following properties:
|
||||
1. `lt`: indicates a string that the name should be less than.
|
||||
2. `gt`: indicates a string that the name should be greater than.
|
||||
3. `gte`: indicates a string that the name should be greater than or equal to.
|
||||
4. `lte`: indicates a string the name should be less than or equal to.
|
||||
2. `config`: This is the second parameter and it is an optional parameter. It’s an object that can have any of the following optional properties:
|
||||
1. `select`: an array of strings indicating the attributes in your location entity to retrieve.
|
||||
2. `skip`: a number indicating how many location records to skip before retrieving the list.
|
||||
3. `take`: a number indicating how many location records to retrieve.
|
||||
4. `order`: an object indicating the order to retrieve the locations by. The order is specified per attribute. So, the attribute in your entity is the property of this object, and the value of the property is either `ASC` or `DESC`.
|
||||
3. `context`: This is the third parameter and it’s an optional parameter. This parameter should be used to inject the transaction manager, as explained in the [Method Decorators section](#using-method-decorators). It’s an object that can have any of the following optional properties:
|
||||
1. `transactionManager`: the transaction manager to use to perform database operations.
|
||||
|
||||
This method is expected to return an array of objects of the following type:
|
||||
|
||||
```ts
|
||||
type StockLocationDTO = {
|
||||
id: string;
|
||||
name: string;
|
||||
metadata: Record<string, unknown> | null;
|
||||
address_id: string;
|
||||
address?: StockLocationAddressDTO;
|
||||
created_at: string | Date;
|
||||
updated_at: string | Date;
|
||||
deleted_at: string | Date | null;
|
||||
}
|
||||
```
|
||||
|
||||
Here’s an example implementation of the method:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
async list(
|
||||
selector: FilterableStockLocationProps,
|
||||
config?: FindConfig<StockLocationDTO> | undefined,
|
||||
@MedusaContext() context?: SharedContext | undefined
|
||||
): Promise<StockLocationDTO[]> {
|
||||
const manager = context.transactionManager!
|
||||
const locationRepo = manager.getRepository(
|
||||
CustomStockLocation
|
||||
)
|
||||
|
||||
// TODO retrieve and return locations
|
||||
// for example
|
||||
return await locationRepo.find(selector)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This example shows how you can use the context to retrieve the transaction manager, then retrieve your repository that you will use to retrieve and return locations. Make sure to replace `CustomStockLocation` with your stock location entity.
|
||||
|
||||
### Implementing listAndCount Method
|
||||
|
||||
This method is similar to the list method, but it returns both the list of locations and a count of the locations.
|
||||
|
||||
It accepts the exact same parameters as the [list method](#implementing-list-method), but expects to return an array of two items. The first one being the list of locations, and the second one being the count of locations.
|
||||
|
||||
Here’s an example implementation of the method:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
async listAndCount(
|
||||
selector: FilterableStockLocationProps,
|
||||
config?: FindConfig<StockLocationDTO> | undefined,
|
||||
@MedusaContext() context?: SharedContext | undefined
|
||||
): Promise<[StockLocationDTO[], number]> {
|
||||
const manager = context.transactionManager!
|
||||
const locationRepo = manager.getRepository(
|
||||
CustomStockLocation
|
||||
)
|
||||
|
||||
// TODO retrieve and return locations
|
||||
// for example
|
||||
return await locationRepo.findAndCount(selector)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to replace `CustomStockLocation` with your stock location entity.
|
||||
|
||||
### Implementing retrieve Method
|
||||
|
||||
This method is used to retrieve a single location. It accepts the following parameters:
|
||||
|
||||
1. `id`: this is the first parameter and is required. It’s a string indicating the ID of the location to retrieve.
|
||||
2. `config`: This is the second parameter and an optional parameter. It’s an object having the same properties as the `config` parameter mentioned in the [list method](#implementing-list-method).
|
||||
3. `context`: This is the third parameter and an optional parameter. It’s of the same type as the `context` parameter mentioned in the [list method](#implementing-list-method).
|
||||
|
||||
This method returns the location as an object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
async retrieve(
|
||||
id: string,
|
||||
config?: FindConfig<StockLocationDTO> | undefined,
|
||||
@MedusaContext() context?: SharedContext | undefined
|
||||
): Promise<StockLocationDTO> {
|
||||
const manager = context.transactionManager!
|
||||
const locationRepo = manager.getRepository(
|
||||
CustomStockLocation
|
||||
)
|
||||
|
||||
// TODO retrieve the location using its ID
|
||||
// for example
|
||||
const [location] = await locationRepo.find({
|
||||
id,
|
||||
})
|
||||
return location
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to replace `CustomStockLocation` with your stock location entity.
|
||||
|
||||
### Implementing create Method
|
||||
|
||||
This method is used to create a new location. It accepts the following parameters:
|
||||
|
||||
1. `input`: This is the first parameter, and it’s required. It's an object holding the following properties:
|
||||
1. `name`: this property is required, and its value is the name of the location.
|
||||
2. `address_id`: this property is optional, and it’s the ID of the address to associate with this location.
|
||||
3. `address`: this property is optional, and it’s an object holding address properties including `address_1`, `country_code`, `city`, and more.
|
||||
4. `metadata`: this property is optional, and it’s an object that should be stored in the `metadata` attribute of the created location.
|
||||
2. `context`: This is the second parameter and an optional parameter. It’s of the same type as the `context` parameter mentioned in the [list method](#implementing-list-method).
|
||||
|
||||
The method is expected to return the created location as an object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
async create(
|
||||
input: CreateStockLocationInput,
|
||||
@MedusaContext() context?: SharedContext | undefined
|
||||
): Promise<StockLocationDTO> {
|
||||
const manager = context.transactionManager!
|
||||
const locationRepo = manager.getRepository(
|
||||
CustomStockLocation
|
||||
)
|
||||
|
||||
// TODO create the location and return it
|
||||
// for example
|
||||
return await locationRepo.create(input)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to replace `CustomStockLocation` with your stock location entity.
|
||||
|
||||
### Implementing update Method
|
||||
|
||||
This method is used to update a location by its ID. It accepts the following parameters:
|
||||
|
||||
1. `id`: this is the first parameter and is required. It’s a string indicating the ID of the location to update.
|
||||
2. `input`: this is the second parameter and is required. It’s an object having any of the following optional properties:
|
||||
1. `name`: a string indicating the name of the location.
|
||||
2. `address_id`: the ID of the address to associate with this location.
|
||||
3. `address`: an object holding address properties including `address_1`, `country_code`, `city`, and more.
|
||||
4. `metadata`: an object that should be stored in the `metadata` attribute of the created location.
|
||||
3. `context`: This is the third parameter and an optional parameter. It’s of the same type as the `context` parameter mentioned in the [list method](#implementing-list-method).
|
||||
|
||||
This method is expected to return the updated location object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
async update(
|
||||
id: string,
|
||||
input: UpdateStockLocationInput,
|
||||
@MedusaContext() context?: SharedContext | undefined
|
||||
): Promise<StockLocationDTO> {
|
||||
const manager = context.transactionManager!
|
||||
const locationRepo = manager.getRepository(
|
||||
CustomStockLocation
|
||||
)
|
||||
|
||||
// TODO update the location and return it
|
||||
// for example
|
||||
await locationRepo.update(id, input)
|
||||
return await this.retrieve(id)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to replace `CustomStockLocation` with your stock location entity.
|
||||
|
||||
### Implementing delete Method
|
||||
|
||||
This method is used to delete a location by its ID. It accepts the following parameters:
|
||||
|
||||
1. `id`: this is the first parameter and is required. It’s a string indicating the ID of the location to delete.
|
||||
2. `context`: This is the second parameter and an optional parameter. It’s of the same type as the `context` parameter mentioned in the [list method](#implementing-list-method).
|
||||
|
||||
This method is not expected to return anything.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
async delete(
|
||||
id: string,
|
||||
@MedusaContext() context?: SharedContext | undefined
|
||||
): Promise<void> {
|
||||
const manager = context.transactionManager!
|
||||
const locationRepo = manager.getRepository(
|
||||
CustomStockLocation
|
||||
)
|
||||
|
||||
// TODO delete the location
|
||||
// for example
|
||||
await locationRepo.delete(id)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to replace `CustomStockLocation` with your stock location entity.
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Use the Stock Location Service
|
||||
|
||||
After implementing your custom service along with any other necessary resources, you can test it out or use it in your Medusa backend. You can learn more about how to do that in the [Create Module documentation](../../../development/modules/create.mdx).
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [How to create an inventory service](./create-inventory-service.md)
|
||||
- [Stock location module architecture](../stock-location-module.md)
|
||||
@@ -22,6 +22,29 @@ Multi-warehouse in Medusa is composed of two modules: an inventory module - whic
|
||||
}
|
||||
}} />
|
||||
|
||||
You can also create your own modules and use them with the Medusa backend.
|
||||
|
||||
<DocCardList colSize={6} items={[
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/multiwarehouse/backend/create-inventory-service',
|
||||
label: 'Backend: Create Inventory Service',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to create an inventory service to be used in a custom inventory module.'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/multiwarehouse/backend/create-stock-location-service',
|
||||
label: 'Backend: Create Stock Location Service',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to create a stock location service to be used in a custom stock location module.'
|
||||
}
|
||||
},
|
||||
]} />
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
@@ -42,12 +65,11 @@ Admins can manage the stock locations, which are the places they store their pro
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '#',
|
||||
href: '/modules/multiwarehouse/admin/manage-stock-locations',
|
||||
label: 'Admin: Manage Stock Locations',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to manage stock locations using admin APIs.',
|
||||
isSoon: true,
|
||||
}
|
||||
},
|
||||
]} />
|
||||
@@ -68,12 +90,11 @@ Admins can manage the inventory of product variants across the different stock l
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '#',
|
||||
href: '/modules/multiwarehouse/admin/manage-inventory-items',
|
||||
label: 'Admin: Manage Inventory',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to manage inventory using the admin APIs.',
|
||||
isSoon: true,
|
||||
}
|
||||
},
|
||||
]} />
|
||||
@@ -94,12 +115,11 @@ Admins can manage item allocations to choose which stock location to fulfill ite
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '#',
|
||||
href: '/modules/multiwarehouse/admin/manage-item-allocations-in-orders',
|
||||
label: 'Admin: Manage Allocations in Orders',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to manage allocations of items in an order using the admin APIs.',
|
||||
isSoon: true,
|
||||
}
|
||||
},
|
||||
]} />
|
||||
|
||||
@@ -932,28 +932,29 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
href: "#",
|
||||
type: "doc",
|
||||
id: "modules/multiwarehouse/backend/create-inventory-service",
|
||||
label: "Backend: Create Inventory Service",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "modules/multiwarehouse/backend/create-stock-location-service",
|
||||
label: "Backend: Create Stock Location Service",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "modules/multiwarehouse/admin/manage-stock-locations",
|
||||
label: "Admin: Manage Stock Locations",
|
||||
customProps: {
|
||||
sidebar_is_soon: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
href: "#",
|
||||
label: "Admin: Manage Inventory",
|
||||
customProps: {
|
||||
sidebar_is_soon: true,
|
||||
},
|
||||
type: "doc",
|
||||
id: "modules/multiwarehouse/admin/manage-inventory-items",
|
||||
label: "Admin: Manage Inventory Items",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
href: "#",
|
||||
type: "doc",
|
||||
id: "modules/multiwarehouse/admin/manage-item-allocations-in-orders",
|
||||
label: "Admin: Manage Allocations in Orders",
|
||||
customProps: {
|
||||
sidebar_is_soon: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -2258,16 +2259,16 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'js-client/overview',
|
||||
label: 'Medusa JS Client',
|
||||
type: "doc",
|
||||
id: "js-client/overview",
|
||||
label: "Medusa JS Client",
|
||||
customProps: {
|
||||
sidebar_is_title: true,
|
||||
sidebar_icon: 'javascript',
|
||||
}
|
||||
sidebar_icon: "javascript",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
type: "category",
|
||||
collapsed: false,
|
||||
label: "Resources",
|
||||
customProps: {
|
||||
@@ -2275,177 +2276,177 @@ module.exports = {
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'admin',
|
||||
type: "category",
|
||||
label: "admin",
|
||||
collapsed: true,
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/Admin',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/Admin",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminAuthResource',
|
||||
label: 'auth',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminAuthResource",
|
||||
label: "auth",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminBatchJobsResource',
|
||||
label: 'batchJobs',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminBatchJobsResource",
|
||||
label: "batchJobs",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminCollectionsResource',
|
||||
label: 'collections',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminCollectionsResource",
|
||||
label: "collections",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminCurrenciesResource',
|
||||
label: 'currencies',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminCurrenciesResource",
|
||||
label: "currencies",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminCustomerGroupsResource',
|
||||
label: 'customerGroups',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminCustomerGroupsResource",
|
||||
label: "customerGroups",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminCustomersResource',
|
||||
label: 'customers',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminCustomersResource",
|
||||
label: "customers",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminDiscountsResource',
|
||||
label: 'discounts',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminDiscountsResource",
|
||||
label: "discounts",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminDraftOrdersResource',
|
||||
label: 'draftOrders',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminDraftOrdersResource",
|
||||
label: "draftOrders",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminGiftCardsResource',
|
||||
label: 'giftCards',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminGiftCardsResource",
|
||||
label: "giftCards",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminInvitesResource',
|
||||
label: 'invites',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminInvitesResource",
|
||||
label: "invites",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminNotesResource',
|
||||
label: 'notes',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminNotesResource",
|
||||
label: "notes",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminNotificationsResource',
|
||||
label: 'notifications',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminNotificationsResource",
|
||||
label: "notifications",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminOrdersResource',
|
||||
label: 'orders',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminOrdersResource",
|
||||
label: "orders",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminOrderEditsResource',
|
||||
label: 'orderEdits',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminOrderEditsResource",
|
||||
label: "orderEdits",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminPriceListResource',
|
||||
label: 'priceLists',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminPriceListResource",
|
||||
label: "priceLists",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminProductsResource',
|
||||
label: 'products',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminProductsResource",
|
||||
label: "products",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminProductTagsResource',
|
||||
label: 'productTags',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminProductTagsResource",
|
||||
label: "productTags",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminProductTypesResource',
|
||||
label: 'productTypes',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminProductTypesResource",
|
||||
label: "productTypes",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminRegionsResource',
|
||||
label: 'regions',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminRegionsResource",
|
||||
label: "regions",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminReturnReasonsResource',
|
||||
label: 'returnReasons',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminReturnReasonsResource",
|
||||
label: "returnReasons",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminReturnsResource',
|
||||
label: 'returns',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminReturnsResource",
|
||||
label: "returns",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminSalesChannelsResource',
|
||||
label: 'salesChannels',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminSalesChannelsResource",
|
||||
label: "salesChannels",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminShippingOptionsResource',
|
||||
label: 'shippingOptions',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminShippingOptionsResource",
|
||||
label: "shippingOptions",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminShippingProfilesResource',
|
||||
label: 'shippingProfiles',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminShippingProfilesResource",
|
||||
label: "shippingProfiles",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminStoresResource',
|
||||
label: 'store',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminStoresResource",
|
||||
label: "store",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminSwapsResource',
|
||||
label: 'swaps',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminSwapsResource",
|
||||
label: "swaps",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminTaxRatesResource',
|
||||
label: 'taxRates',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminTaxRatesResource",
|
||||
label: "taxRates",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminUploadsResource',
|
||||
label: 'uploads',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminUploadsResource",
|
||||
label: "uploads",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminUsersResource',
|
||||
label: 'users',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminUsersResource",
|
||||
label: "users",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AdminVariantsResource',
|
||||
label: 'variants',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AdminVariantsResource",
|
||||
label: "variants",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/AuthResource',
|
||||
label: 'auth',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/AuthResource",
|
||||
label: "auth",
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'carts',
|
||||
type: "category",
|
||||
label: "carts",
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/CartsResource',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/CartsResource",
|
||||
},
|
||||
collapsed: true,
|
||||
items: [
|
||||
@@ -2457,17 +2458,17 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/CollectionsResource',
|
||||
label: 'collections',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/CollectionsResource",
|
||||
label: "collections",
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'customers',
|
||||
type: "category",
|
||||
label: "customers",
|
||||
collapsed: true,
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/CustomerResource',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/CustomerResource",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
@@ -2483,31 +2484,31 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/GiftCardsResource',
|
||||
label: 'giftCards',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/GiftCardsResource",
|
||||
label: "giftCards",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/OrdersResource',
|
||||
label: 'orders',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/OrdersResource",
|
||||
label: "orders",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/OrderEditsResource',
|
||||
label: 'orderEdits',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/OrderEditsResource",
|
||||
label: "orderEdits",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/PaymentMethodsResource',
|
||||
label: 'paymentMethods',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/PaymentMethodsResource",
|
||||
label: "paymentMethods",
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'products',
|
||||
type: "category",
|
||||
label: "products",
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/ProductsResource',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/ProductsResource",
|
||||
},
|
||||
collapsed: true,
|
||||
items: [
|
||||
@@ -2519,29 +2520,29 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/RegionsResource',
|
||||
label: 'regions',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/RegionsResource",
|
||||
label: "regions",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/ReturnReasonsResource',
|
||||
label: 'returnReasons',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/ReturnReasonsResource",
|
||||
label: "returnReasons",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/ReturnsResource',
|
||||
label: 'returns',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/ReturnsResource",
|
||||
label: "returns",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/ShippingOptionsResource',
|
||||
label: 'shippingOptions',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/ShippingOptionsResource",
|
||||
label: "shippingOptions",
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'references/js-client/classes/SwapsResource',
|
||||
label: 'swaps',
|
||||
type: "doc",
|
||||
id: "references/js-client/classes/SwapsResource",
|
||||
label: "swaps",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user