From 178a7f42164ff54246a784ad05f1cc39c13af773 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Mon, 3 Feb 2025 18:14:45 +0200 Subject: [PATCH] docs: document variant inventory conceptual guide (#11280) * docs: document variant inventory conceptual guide * add notes * fix vale error * fix vale error --- .../inventory/links-to-other-modules/page.mdx | 6 ++ .../product/links-to-other-modules/page.mdx | 6 ++ .../product/variant-inventory/page.mdx | 84 +++++++++++++++++++ www/apps/resources/generated/edit-dates.mjs | 7 +- www/apps/resources/generated/files-map.mjs | 4 + www/apps/resources/generated/sidebar.mjs | 54 ++++++++++-- www/apps/resources/sidebars/inventory.mjs | 2 + www/apps/resources/sidebars/product.mjs | 5 ++ www/apps/resources/sidebars/sales-channel.mjs | 2 + .../resources/sidebars/stock-location.mjs | 2 + www/packages/tags/src/tags/concept.ts | 4 + www/packages/tags/src/tags/index.ts | 50 +++++------ www/packages/tags/src/tags/inventory.ts | 4 + www/packages/tags/src/tags/locking.ts | 16 ++++ www/packages/tags/src/tags/order.ts | 4 - www/packages/tags/src/tags/sales-channel.ts | 4 + www/packages/tags/src/tags/step.ts | 4 - www/packages/tags/src/tags/stock-location.ts | 4 + 18 files changed, 218 insertions(+), 44 deletions(-) create mode 100644 www/apps/resources/app/commerce-modules/product/variant-inventory/page.mdx diff --git a/www/apps/resources/app/commerce-modules/inventory/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/inventory/links-to-other-modules/page.mdx index c4cc120149..bcb82e0f52 100644 --- a/www/apps/resources/app/commerce-modules/inventory/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/inventory/links-to-other-modules/page.mdx @@ -31,6 +31,12 @@ Each product variant has different inventory details. Medusa defines a link betw A product variant whose `manage_inventory` property is enabled has an associated inventory item. Through that inventory's items relations in the Inventory Module, you can manage and check the variant's inventory quantity. + + +Learn more about product variant's inventory management in [this guide](../../product/variant-inventory/page.mdx). + + + ### Retrieve with Query To retrieve the product variants of an inventory item with [Query](!docs!/learn/fundamentals/module-links/query), pass `variants.*` in `fields`: diff --git a/www/apps/resources/app/commerce-modules/product/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/product/links-to-other-modules/page.mdx index 76c05829b9..9da14e6737 100644 --- a/www/apps/resources/app/commerce-modules/product/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/links-to-other-modules/page.mdx @@ -90,6 +90,12 @@ Medusa defines a link between the `ProductVariant` and `InventoryItem` data mode When the `manage_inventory` property of a product variant is enabled, you can manage the variant's inventory in different locations through this relation. + + +Learn more about product variant's inventory management in [this guide](../variant-inventory/page.mdx). + + + ### Retrieve with Query To retrieve the inventory items of a product variant with [Query](!docs!/learn/fundamentals/module-links/query), pass `inventory_items.*` in `fields`: diff --git a/www/apps/resources/app/commerce-modules/product/variant-inventory/page.mdx b/www/apps/resources/app/commerce-modules/product/variant-inventory/page.mdx new file mode 100644 index 0000000000..ede7e77bc4 --- /dev/null +++ b/www/apps/resources/app/commerce-modules/product/variant-inventory/page.mdx @@ -0,0 +1,84 @@ +--- +title: "Product Variant Inventory" +tags: + - concept + - inventory + - stock location + - sales channel +--- + +export const metadata = { + title: `Product Variant Inventory`, +} + +# {metadata.title} + +In this guide, you'll learn about the inventory management features related to product variants. + +## Configure Inventory Management of Product Variants + +A product variant, represented by the [ProductVariant](/references/product/models/ProductVariant) data model, has a `manage_inventory` field that's disabled by default. This field indicates whether you'll manage the inventory quantity of the product variant. + +The Product Module doesn't provide inventory-management features. Instead, the Medusa application uses the [Inventory Module](../../inventory/page.mdx) to manage inventory for products and variants. When `manage_inventory` is disabled, the Medusa application always considers the product variant to be in stock. This is useful if your product's variants aren't items that can be stocked, such as digital products, or they don't have a limited stock quantity. + +When `manage_inventory` is enabled, the Medusa application tracks the inventory of the product variant using the [Inventory Module](../../inventory/page.mdx). For example, when a customer purchases a product variant, the Medusa application decrements the stocked quantity of the product variant. + +--- + +## How the Medusa Application Manages Inventory + +When a product variant has `manage_inventory` enabled, the Medusa application creates an inventory item using the [Inventory Module](../../inventory/page.mdx) and links it to the product variant. + +![Diagram showcasing the link between a product variant and its inventory item](https://res.cloudinary.com/dza7lstvk/image/upload/v1709652779/Medusa%20Resources/product-inventory_kmjnud.jpg) + +The inventory item has one or more locations, called inventory levels, that represent the stock quantity of the product variant at a specific location. This allows you to manage inventory across multiple warehouses, such as a warehouse in the US and another in Europe. + +![Diagram showcasing the link between a variant and its inventory item, and the inventory item's level.](https://res.cloudinary.com/dza7lstvk/image/upload/v1738580390/Medusa%20Resources/variant-inventory-level_bbee2t.jpg) + + + +Learn more about inventory concepts in the [Inventory Module's documentation](../../inventory/concepts/page.mdx). + + + +The Medusa application represents and manages stock locations using the [Stock Location Module](../../stock-location/page.mdx). It creates a read-only link between the `InventoryLevel` and `StockLocation` data models so that it can retrieve the stock location of an inventory level. + +![Diagram showcasing the read-only link between an inventory level and a stock location](https://res.cloudinary.com/dza7lstvk/image/upload/v1738582163/Medusa%20Resources/inventory-level-stock_amxfg5.jpg) + + + +Learn more about the Stock Location Module in the [Stock Location Module's documentation](../../stock-location/concepts/page.mdx). + + + +### Product Inventory in Storefronts + +When a storefront sends a request to the Medusa application, it must always pass a [publishable API key](../../sales-channel/publishable-api-keys/page.mdx) in the request header. This API key specifies the sales channels, available through the [Sales Channel Module](../../sales-channel/page.mdx), of the storefront. + +The Medusa application links sales channels to stock locations, indicating the locations available for a specific sales channel. So, all inventory-related operations are scoped by the sales channel and its associated stock locations. + +For example, the availability of a product variant is determined by the `stocked_quantity` of its inventory level at the stock location linked to the storefront's sales channel. + +![Diagram showcasing the overall relations between inventory, stock location, and sales channel concepts](https://res.cloudinary.com/dza7lstvk/image/upload/v1738582163/Medusa%20Resources/inventory-stock-sales_fknoxw.jpg) + +--- + +## Variant Back Orders + +Product variants have an `allow_backorder` field that's disabled by default. When enabled, the Medusa application allows customers to purchase the product variant even when it's out of stock. Use this when your product variant is available through on-demand or pre-order purchase. + + + +You can also allow customers to subscribe to restock notifications of a product variant as explained in [this guide](../../../recipes/commerce-automation/restock-notification/page.mdx). + + + +--- + +## Additional Resources + +The following guides provide more details on inventory management in the Medusa application: + +- [Inventory Kits in the Inventory Module](../../inventory/inventory-kit/page.mdx): Learn how you can implement bundled or multi-part products through the Inventory Module. +- [Inventory in Flows](../../inventory/inventory-in-flows/page.mdx): Learn how Medusa utilizes inventory management in different flows. +- [Storefront guide: how to retrieve a product variant's inventory details](https://docs.medusajs.com/resources/storefront-development/products/inventory). diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index b50883ff4e..a893729f5c 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -2115,10 +2115,10 @@ export const generatedEditDates = { "app/commerce-modules/cart/links-to-other-modules/page.mdx": "2025-01-06T11:19:35.593Z", "app/commerce-modules/customer/extend/page.mdx": "2024-12-25T15:54:37.789Z", "app/commerce-modules/fulfillment/links-to-other-modules/page.mdx": "2025-01-06T11:19:35.593Z", - "app/commerce-modules/inventory/links-to-other-modules/page.mdx": "2025-01-06T11:19:35.600Z", + "app/commerce-modules/inventory/links-to-other-modules/page.mdx": "2025-02-03T12:37:33.622Z", "app/commerce-modules/pricing/links-to-other-modules/page.mdx": "2025-01-06T11:19:35.607Z", "app/commerce-modules/product/extend/page.mdx": "2024-12-11T09:07:25.252Z", - "app/commerce-modules/product/links-to-other-modules/page.mdx": "2025-01-06T11:19:35.606Z", + "app/commerce-modules/product/links-to-other-modules/page.mdx": "2025-02-03T12:37:18.919Z", "app/commerce-modules/promotion/extend/page.mdx": "2024-12-11T09:07:24.137Z", "app/commerce-modules/promotion/links-to-other-modules/page.mdx": "2025-01-06T11:19:35.608Z", "app/commerce-modules/order/edit/page.mdx": "2024-10-09T08:50:05.334Z", @@ -5902,5 +5902,6 @@ export const generatedEditDates = { "references/types/HttpTypes/interfaces/types.HttpTypes.StoreProductTypeResponse/page.mdx": "2025-01-27T11:43:54.212Z", "references/types/interfaces/types.BaseProductTypeListParams/page.mdx": "2025-01-27T11:43:54.550Z", "references/core_flows/Order/Steps_Order/variables/core_flows.Order.Steps_Order.updateOrderChangesStepId/page.mdx": "2025-01-27T11:43:49.278Z", - "app/troubleshooting/test-errors/page.mdx": "2025-01-31T13:08:42.639Z" + "app/troubleshooting/test-errors/page.mdx": "2025-01-31T13:08:42.639Z", + "app/commerce-modules/product/variant-inventory/page.mdx": "2025-02-03T12:19:45.706Z" } \ No newline at end of file diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index e42188a94a..0cdecd2a24 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -551,6 +551,10 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/product/page.mdx", "pathname": "/commerce-modules/product" }, + { + "filePath": "/www/apps/resources/app/commerce-modules/product/variant-inventory/page.mdx", + "pathname": "/commerce-modules/product/variant-inventory" + }, { "filePath": "/www/apps/resources/app/commerce-modules/product/workflows/page.mdx", "pathname": "/commerce-modules/product/workflows" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index b28897ab30..9b0de1c826 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -4626,6 +4626,8 @@ export const generatedSidebar = [ "type": "category", "title": "Concepts", "initialOpen": false, + "autogenerate_tags": "concept+inventory", + "autogenerate_as_ref": true, "children": [ { "loaded": true, @@ -4658,6 +4660,14 @@ export const generatedSidebar = [ "path": "/commerce-modules/inventory/links-to-other-modules", "title": "Links to Modules", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Product Variant Inventory", + "path": "/commerce-modules/product/variant-inventory", + "children": [] } ] }, @@ -6647,14 +6657,6 @@ export const generatedSidebar = [ "path": "/references/medusa-workflows/steps/updateOrderChangesStep", "children": [] }, - { - "loaded": true, - "isPathHref": true, - "type": "ref", - "title": "updateOrderExchangesStep", - "path": "/references/medusa-workflows/steps/updateOrderExchangesStep", - "children": [] - }, { "loaded": true, "isPathHref": true, @@ -10338,6 +10340,14 @@ export const generatedSidebar = [ "autogenerate_tags": "concept+product", "autogenerate_as_ref": true, "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/commerce-modules/product/variant-inventory", + "title": "Variant Inventory", + "children": [] + }, { "loaded": true, "isPathHref": true, @@ -13200,6 +13210,8 @@ export const generatedSidebar = [ "type": "category", "title": "Concepts", "initialOpen": false, + "autogenerate_tags": "concept+salesChannel", + "autogenerate_as_ref": true, "children": [ { "loaded": true, @@ -13216,6 +13228,14 @@ export const generatedSidebar = [ "path": "/commerce-modules/sales-channel/links-to-other-modules", "title": "Links to Modules", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Product Variant Inventory", + "path": "/commerce-modules/product/variant-inventory", + "children": [] } ] }, @@ -13640,6 +13660,8 @@ export const generatedSidebar = [ "type": "category", "title": "Concepts", "initialOpen": false, + "autogenerate_tags": "concept+stockLocation", + "autogenerate_as_ref": true, "children": [ { "loaded": true, @@ -13656,6 +13678,22 @@ export const generatedSidebar = [ "path": "/commerce-modules/stock-location/links-to-other-modules", "title": "Links to Modules", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Inventory Kits", + "path": "/commerce-modules/inventory/inventory-kit", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Product Variant Inventory", + "path": "/commerce-modules/product/variant-inventory", + "children": [] } ] }, diff --git a/www/apps/resources/sidebars/inventory.mjs b/www/apps/resources/sidebars/inventory.mjs index 1f263f409a..81f01b02b6 100644 --- a/www/apps/resources/sidebars/inventory.mjs +++ b/www/apps/resources/sidebars/inventory.mjs @@ -17,6 +17,8 @@ export const inventorySidebar = [ type: "category", title: "Concepts", initialOpen: false, + autogenerate_tags: "concept+inventory", + autogenerate_as_ref: true, children: [ { type: "link", diff --git a/www/apps/resources/sidebars/product.mjs b/www/apps/resources/sidebars/product.mjs index e9e7080d2a..0f21f6582e 100644 --- a/www/apps/resources/sidebars/product.mjs +++ b/www/apps/resources/sidebars/product.mjs @@ -20,6 +20,11 @@ export const productSidebar = [ autogenerate_tags: "concept+product", autogenerate_as_ref: true, children: [ + { + type: "link", + path: "/commerce-modules/product/variant-inventory", + title: "Variant Inventory", + }, { type: "link", path: "/commerce-modules/product/links-to-other-modules", diff --git a/www/apps/resources/sidebars/sales-channel.mjs b/www/apps/resources/sidebars/sales-channel.mjs index 4386034336..f4bee4e912 100644 --- a/www/apps/resources/sidebars/sales-channel.mjs +++ b/www/apps/resources/sidebars/sales-channel.mjs @@ -17,6 +17,8 @@ export const salesChannelSidebar = [ type: "category", title: "Concepts", initialOpen: false, + autogenerate_tags: "concept+salesChannel", + autogenerate_as_ref: true, children: [ { type: "link", diff --git a/www/apps/resources/sidebars/stock-location.mjs b/www/apps/resources/sidebars/stock-location.mjs index 79c2860dc0..2335a938f1 100644 --- a/www/apps/resources/sidebars/stock-location.mjs +++ b/www/apps/resources/sidebars/stock-location.mjs @@ -17,6 +17,8 @@ export const stockLocationSidebar = [ type: "category", title: "Concepts", initialOpen: false, + autogenerate_tags: "concept+stockLocation", + autogenerate_as_ref: true, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/concept.ts b/www/packages/tags/src/tags/concept.ts index da7bc2c3f1..1c2666f270 100644 --- a/www/packages/tags/src/tags/concept.ts +++ b/www/packages/tags/src/tags/concept.ts @@ -2,5 +2,9 @@ export const concept = [ { "title": "Inventory Kits", "path": "/commerce-modules/inventory/inventory-kit" + }, + { + "title": "Product Variant Inventory", + "path": "/commerce-modules/product/variant-inventory" } ] \ No newline at end of file diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index d0f0518177..4683731d7c 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,37 +1,37 @@ export * from "./inventory.js" export * from "./pricing.js" -export * from "./tax.js" export * from "./concept.js" -export * from "./storefront.js" export * from "./query.js" +export * from "./sales-channel.js" +export * from "./tax.js" +export * from "./storefront.js" export * from "./payment.js" -export * from "./cart.js" export * from "./order.js" -export * from "./stripe.js" -export * from "./customer.js" +export * from "./cart.js" +export * from "./product.js" +export * from "./server.js" +export * from "./stock-location.js" +export * from "./product-collection.js" export * from "./fulfillment.js" export * from "./auth.js" -export * from "./product-category.js" -export * from "./publishable-api-key.js" -export * from "./sales-channel.js" -export * from "./region.js" export * from "./api-key.js" -export * from "./step.js" -export * from "./workflow.js" -export * from "./product-collection.js" +export * from "./stripe.js" +export * from "./region.js" +export * from "./product-category.js" +export * from "./customer.js" export * from "./remote-query.js" +export * from "./step.js" export * from "./link.js" -export * from "./event-bus.js" -export * from "./product.js" -export * from "./locking.js" -export * from "./logger.js" -export * from "./file.js" -export * from "./admin.js" -export * from "./promotion.js" -export * from "./notification.js" -export * from "./user.js" -export * from "./server.js" -export * from "./js-sdk.js" -export * from "./stock-location.js" -export * from "./currency.js" export * from "./store.js" +export * from "./publishable-api-key.js" +export * from "./event-bus.js" +export * from "./logger.js" +export * from "./promotion.js" +export * from "./user.js" +export * from "./notification.js" +export * from "./js-sdk.js" +export * from "./currency.js" +export * from "./file.js" +export * from "./locking.js" +export * from "./admin.js" +export * from "./workflow.js" diff --git a/www/packages/tags/src/tags/inventory.ts b/www/packages/tags/src/tags/inventory.ts index 4fc8227e7d..62f3a2b0b5 100644 --- a/www/packages/tags/src/tags/inventory.ts +++ b/www/packages/tags/src/tags/inventory.ts @@ -3,6 +3,10 @@ export const inventory = [ "title": "Inventory Kits", "path": "/commerce-modules/inventory/inventory-kit" }, + { + "title": "Product Variant Inventory", + "path": "/commerce-modules/product/variant-inventory" + }, { "title": "Retrieve Product Variant's Inventory in Storefront", "path": "/storefront-development/products/inventory" diff --git a/www/packages/tags/src/tags/locking.ts b/www/packages/tags/src/tags/locking.ts index 7bfee689fe..19bb15ee08 100644 --- a/www/packages/tags/src/tags/locking.ts +++ b/www/packages/tags/src/tags/locking.ts @@ -7,6 +7,14 @@ export const locking = [ "title": "completeCartWorkflow", "path": "/references/medusa-workflows/completeCartWorkflow" }, + { + "title": "adjustInventoryLevelsStep", + "path": "/references/medusa-workflows/steps/adjustInventoryLevelsStep" + }, + { + "title": "cancelOrderFulfillmentWorkflow", + "path": "/references/medusa-workflows/cancelOrderFulfillmentWorkflow" + }, { "title": "confirmClaimRequestWorkflow", "path": "/references/medusa-workflows/confirmClaimRequestWorkflow" @@ -19,6 +27,14 @@ export const locking = [ "title": "confirmOrderEditRequestWorkflow", "path": "/references/medusa-workflows/confirmOrderEditRequestWorkflow" }, + { + "title": "confirmReturnReceiveWorkflow", + "path": "/references/medusa-workflows/confirmReturnReceiveWorkflow" + }, + { + "title": "createOrderFulfillmentWorkflow", + "path": "/references/medusa-workflows/createOrderFulfillmentWorkflow" + }, { "title": "createReservationsStep", "path": "/references/medusa-workflows/steps/createReservationsStep" diff --git a/www/packages/tags/src/tags/order.ts b/www/packages/tags/src/tags/order.ts index 74f43befde..f8425eb3a1 100644 --- a/www/packages/tags/src/tags/order.ts +++ b/www/packages/tags/src/tags/order.ts @@ -135,10 +135,6 @@ export const order = [ "title": "updateOrderChangesStep", "path": "/references/medusa-workflows/steps/updateOrderChangesStep" }, - { - "title": "updateOrderExchangesStep", - "path": "/references/medusa-workflows/steps/updateOrderExchangesStep" - }, { "title": "updateOrderShippingMethodsStep", "path": "/references/medusa-workflows/steps/updateOrderShippingMethodsStep" diff --git a/www/packages/tags/src/tags/sales-channel.ts b/www/packages/tags/src/tags/sales-channel.ts index 176c521eae..57f4c2e0ec 100644 --- a/www/packages/tags/src/tags/sales-channel.ts +++ b/www/packages/tags/src/tags/sales-channel.ts @@ -1,4 +1,8 @@ export const salesChannel = [ + { + "title": "Product Variant Inventory", + "path": "/commerce-modules/product/variant-inventory" + }, { "title": "Use a Publishable API Key in the Storefront", "path": "/storefront-development/publishable-api-keys" diff --git a/www/packages/tags/src/tags/step.ts b/www/packages/tags/src/tags/step.ts index 201bb79c45..9139b6ec66 100644 --- a/www/packages/tags/src/tags/step.ts +++ b/www/packages/tags/src/tags/step.ts @@ -535,10 +535,6 @@ export const step = [ "title": "updateOrderChangesStep", "path": "/references/medusa-workflows/steps/updateOrderChangesStep" }, - { - "title": "updateOrderExchangesStep", - "path": "/references/medusa-workflows/steps/updateOrderExchangesStep" - }, { "title": "updateOrderShippingMethodsStep", "path": "/references/medusa-workflows/steps/updateOrderShippingMethodsStep" diff --git a/www/packages/tags/src/tags/stock-location.ts b/www/packages/tags/src/tags/stock-location.ts index 379dd13417..3696eecc97 100644 --- a/www/packages/tags/src/tags/stock-location.ts +++ b/www/packages/tags/src/tags/stock-location.ts @@ -3,6 +3,10 @@ export const stockLocation = [ "title": "Inventory Kits", "path": "/commerce-modules/inventory/inventory-kit" }, + { + "title": "Product Variant Inventory", + "path": "/commerce-modules/product/variant-inventory" + }, { "title": "createStockLocations", "path": "/references/medusa-workflows/steps/createStockLocations"