[IMP] inventory: sell stock virtual warehouse

closes odoo/documentation#7759

X-original-commit: 98994fbbaa
Signed-off-by: Felicia Kuan (feku) <feku@odoo.com>
Co-authored-by: hojo-odoo <123424465+hojo-odoo@users.noreply.github.com>
Co-authored-by: ksc-odoo <73958186+ksc-odoo@users.noreply.github.com>
This commit is contained in:
Felicious 2024-01-13 00:35:13 +00:00
parent 1d04f0c761
commit 3d83bec933
10 changed files with 170 additions and 131 deletions

View File

@ -14,6 +14,8 @@ for warehouses in Odoo is one step receipts and deliveries.
In the following example, one step will be used for both receipts and deliveries. In the following example, one step will be used for both receipts and deliveries.
.. _inventory/receipts_delivery_one_step/wh:
Configure the warehouse Configure the warehouse
======================= =======================

View File

@ -39,7 +39,7 @@ The receiving and shipping rules for a one-step configuration are as follows:
- Items are received or shipped directly into/from stock. - Items are received or shipped directly into/from stock.
.. seealso:: .. seealso::
:ref:`Process receipts and deliveries in one step <inventory/receipts_delivery_one_step>` :doc:`receipts_delivery_one_step`
Two-step flow Two-step flow
------------- -------------

View File

@ -6,189 +6,226 @@ While keeping stock and selling inventory from one warehouse might work for smal
bigger companies might need to keep stock in, or sell from, multiple warehouses in multiple bigger companies might need to keep stock in, or sell from, multiple warehouses in multiple
locations. locations.
In Odoo, sometimes products included in a single sales order might take stock from two (or more) Sometimes products included in a single sales order might take stock from two (or more) warehouses;
warehouses. In Odoo, pulling products from multiple warehouses to satisfy sales demands can be done in Odoo, pulling products from multiple warehouses to satisfy sales demands can be done using
by using *virtual locations*. *virtual locations*.
.. important::
The solution in this document, describing the use of a virtual warehouse to fulfill orders for
multiple warehouses, has some limitations. Consider the following before proceeding:
#. When the :guilabel:`Warehouse` field is set to a virtual warehouse on a sales order, the
virtual warehouse's address is indicated on the picking, packing, and delivery forms, **not**
the actual warehouse's address.
#. Each location has a `warehouse_id` (hidden field). This means that the stock in the virtual
warehouse will **not** be the sum of the stock of the real warehouses, but rather the sum of
the stock in the locations whose warehouse ID is the virtual warehouse.
.. danger::
Potential limitation for those using :doc:`two
<../../shipping_receiving/daily_operations/receipts_delivery_two_steps>` or :doc:`three-step
delivery <../../shipping_receiving/daily_operations/delivery_three_steps>`:
#. The output or packing zone on the various forms is incorrectly listed as the virtual
warehouse's address.
#. There is no workaround for two or three-step deliveries.
#. Proceed **only** if setting a virtual warehouse's address as the output or packing zone makes
sense for the company's workflow.
.. note:: .. note::
In order to create virtual locations in warehouses and proceed to the following steps, In order to create virtual locations in warehouses, and proceed to the following steps, the
the :guilabel:`Storage Locations` and :guilabel:`Multi-Step Routes` features will need to be :guilabel:`Storage Locations` and :guilabel:`Multi-Step Routes` features **must** be enabled.
enabled in the :menuselection:`Settings` app.
To do so, go to :menuselection:`Inventory --> Configuration --> Settings`, scroll down to the To do so, go to :menuselection:`Inventory app --> Configuration --> Settings`, scroll down to the
:guilabel:`Warehouse` section, and click the checkboxes next to :guilabel:`Storage Locations` :guilabel:`Warehouse` section, and enable the :guilabel:`Storage Locations` and
and :guilabel:`Multi-Step Routes`. Then, :guilabel:`Save` the changes to finish. :guilabel:`Multi-Step Routes` options. Then, :guilabel:`Save` the changes to finish.
Create and configure a virtual parent location
==============================================
Before creating any virtual stock locations, a new warehouse will need to be created. This new .. _inventory/routes/virtual-wh:
warehouse will act as a *virtual* warehouse, and will be the *parent* location of other physical
warehouses. Create virtual parent location
==============================
Before creating any virtual stock locations, create a new warehouse that acts as a *virtual*
warehouse — the *parent* location of other physical warehouses.
.. spoiler:: Why a "virtual" warehouse? .. spoiler:: Why a "virtual" warehouse?
Virtual warehouses are great for companies with multiple physical warehouses. This is because Virtual warehouses are great for companies with multiple physical warehouses. This is because a
a situation might arise when one warehouse runs out of stock of a particular product, but situation might arise when one warehouse runs out of stock of a particular product, but another
another warehouse still has stock on-hand. In this case, stock from these two (or more) warehouse still has stock on-hand. In this case, stock from these two (or more) warehouses could
warehouses could be used to fulfill a single sales order. be used to fulfill a single sales order.
The "virtual" warehouse acts as a single aggregator of all the inventory stored in a company's The "virtual" warehouse acts as a single aggregator of all the inventory stored in a company's
physical warehouses, and is used (for traceability purposes) to create a hierarchy of locations physical warehouses, and is used (for traceability purposes) to create a hierarchy of locations
in Odoo. in Odoo.
Create a new warehouse To create a new warehouse, go to :menuselection:`Inventory app --> Configuration --> Warehouses`,
---------------------- and click :guilabel:`Create`. From here, the warehouse :guilabel:`Name` and :guilabel:`Short Name`
can be changed, and other warehouse details can be changed under the :guilabel:`Warehouse
Configuration` tab.
To create a new warehouse, go to :menuselection:`Inventory --> Configuration --> Warehouses`, and Lastly, click :guilabel:`Save` to finish creating a *regular* warehouse. Continue following the
click :guilabel:`Create`. From here, the warehouse :guilabel:`Name` and :guilabel:`Short Name` can steps below to finish configuring the virtual parent warehouse.
be changed, and other warehouse details can be changed under the :guilabel:`Warehouse Configuration`
tab.
Under the :guilabel:`Shipments` heading, set the number of steps used to process :guilabel:`Incoming
Shipments` and :guilabel:`Outgoing Shipments` by selecting between the :guilabel:`1 step`,
:guilabel:`2 steps`, and :guilabel:`3 steps` radio buttons. The desired option for
:guilabel:`Incoming Shipments` and :guilabel:`Outgoing Shipments` will depend on the warehouse's
procurement process, and might differ for individual products or product categories.
.. seealso::
- :doc:`How to choose the right flow to handle receipts and deliveries?
</applications/inventory_and_mrp/inventory/shipping_receiving/daily_operations/shipments_deliveries>`
Under the :guilabel:`Resupply` heading, configure the method(s) for how the warehouse resupplies
its inventory:
- :guilabel:`Resupply Subcontractors`: resupply subcontractors with components from this warehouse.
- :guilabel:`Manufacture to Resupply`: when products are manufactured, they can be manufactured in
this warehouse.
- :guilabel:`Manufacture`: to produce right away, move the components to the production location
directly and start the manufacturing process; to pick first and then produce, unload the
components from the stock to input location first, and then transfer it to the production
location.
- :guilabel:`Buy to Resupply`: when products are bought, they can be delivered to this warehouse.
- :guilabel:`Resupply From`: automatically create routes to resupply this warehouse from another
chosen warehouse
.. tip::
*Routes* can be set and configured directly from the :guilabel:`Warehouse` form, by clicking on
the :guilabel:`Routes` smart button. Once the warehouse is configured, virtual *Locations* can be
created.
.. image:: stock_warehouses/stock-warehouses-create-warehouse.png .. image:: stock_warehouses/stock-warehouses-create-warehouse.png
:align: center :align: center
:alt: The edit screen for creating a new warehouse. :alt: New warehouse form.
In order to apply this virtual warehouse as the *parent* location of two *child* location .. seealso::
warehouses, there need to be two warehouses configured with physical stock locations. - :doc:`Warehouse configurations <../inventory_management/warehouses_locations>`
- :ref:`Incoming and outgoing shipments <inventory/receipts_delivery_one_step/wh>`
- :doc:`Resupply from another warehouse <../inventory_management/resupply_warehouses>`
.. _inventory/routes/child-wh:
Create child warehouses
=======================
Create at least two *child* warehouses to link to the virtual warehouse.
.. important::
In order to take stock from multiple warehouses to fulfill a sales order, there needs to be at
least **two** warehouses acting as child locations of the virtual parent location warehouse.
To do that, navigate to :menuselection:`Inventory app --> Configuration --> Warehouses`, click
:guilabel:`Create`, and follow the :ref:`preceding instructions <inventory/routes/virtual-wh>` to
configure the physical stock locations.
.. example:: .. example::
| **Parent Warehouse** | **Parent Warehouse**
| :guilabel:`Warehouse`: `Virtual Warehouse` | :guilabel:`Warehouse`: `Virtual Warehouse`
| :guilabel:`Location`: `VWH` | :guilabel:`Location`: `VWH/Stock`
| **Child Warehouses** | **Child Warehouses**
| :guilabel:`Warehouses`: `Warehouse A` and `Warehouse B` | :guilabel:`Warehouses`: `Warehouse A` and `Warehouse B`
| :guilabel:`Locations`: `WHA/Stock` and `WHB/Stock` | :guilabel:`Locations`: `WHA` and `WHB`
Create a virtual parent location .. image:: stock_warehouses/parent-location.png
-------------------------------- :align: center
:alt: Graphic of child locations 'WHA' and 'WHB' tied to the parent location.
.. important:: .. important::
In order to take stock from multiple warehouses to fulfill a sales order, there need to be at While the virtual stock location will be changed to 'View' later, the :guilabel:`Location Type`
least **two** warehouses acting as *child locations* of the *virtual parent location* warehouse. **must** be :guilabel:`Internal Location` at this point to :ref:`link the child warehouses
<inventory/routes/link-to-vwh>` in the next section.
To create and edit *Locations*, go to :menuselection:`Inventory --> Configuration --> Locations`. .. _inventory/routes/link-to-vwh:
All :guilabel:`Locations` are listed here, including the *Stock* :guilabel:`Location` of the virtual
warehouse that was created. Click into the *Stock* :guilabel:`Location` for the virtual warehouse
that was previously created (:dfn:`Warehouse Name/Stock`).
Then, under the :guilabel:`Additional Information` section, change the :guilabel:`Location Type` Link child warehouses to virtual stock
from :guilabel:`Internal Location` to :guilabel:`View`. :guilabel:`Save` the changes. ======================================
This identifies this :guilabel:`Location` as a *virtual location*, which is used to create a To set physical warehouses as child locations of the virtual location configured in the
hierarchical structure for a warehouse and aggregate its *child locations*. :ref:`previous step <inventory/routes/virtual-wh>`, navigate to :menuselection:`Inventory app -->
Configuration --> Locations`.
.. note:: Remove any filters from the search bar. Then, click the physical warehouse :guilabel:`Location` that
Products can *not* be stored in a :guilabel:`View` :guilabel:`Location Type`. was previously created to be a child location (e.g. `WHA`), and click :guilabel:`Edit`.
.. image:: stock_warehouses/stock-warehouses-location-types.png Change the :guilabel:`Parent Location` field from :guilabel:`Physical Locations` to the virtual
warehouse's **stock location** (e.g. `VWH/Stock`) from the drop-down menu, and click
:guilabel:`Save`.
.. important::
To select the virtual warehouse's stock location in the :guilabel:`Parent Location` drop-down
menu, the parent warehouse stock location (e.g. `VWH/Stock`) **must** have its
:guilabel:`Location Type` set to :guilabel:`Internal Location`.
.. image:: stock_warehouses/configure-physical-wh.png
:align: center
:alt: Set the child warehouse's *Parent Location* to the virtual warehouse.
Repeat the preceding steps to configure two or more child warehouses.
Once complete, the virtual, parent warehouse (e.g. `VWH/Stock`) fulfills orders using stock from
child warehouses (e.g. `WHA` and `WHB`), if there is insufficient stock in any one location.
Set virtual stock location as 'view'
====================================
Set the virtual stock location's :guilabel:`Location Type` to :guilabel:`View`, as it is a
non-existent location used to group various physical warehouses together.
To do that, navigate to :menuselection:`Inventory app --> Configuration --> Locations`.
Click the virtual warehouse's stock location (e.g. `VWH/Stock`) that was :ref:`previously created
<inventory/routes/virtual-wh>`, from the :guilabel:`Locations` list.
On the location form, under the :guilabel:`Additional Information` heading, set the
:guilabel:`Location Type` to :guilabel:`View`. :guilabel:`Save` the changes.
.. image:: stock_warehouses/set-location-type-view.png
:align: center :align: center
:alt: Warehouse location types in location creation screen. :alt: Warehouse location types in location creation screen.
Configure physical warehouse locations .. tip::
====================================== To view the total quantity across **all** linked child warehouses, go to the product form and
click the :guilabel:`On Hand` smart button.
Navigate back to the :guilabel:`Locations` overview (via the breadcrumbs), and remove any filters .. image:: stock_warehouses/on-hand.png
in the :guilabel:`Search Bar`. Then, click into the first physical warehouse :guilabel:`Location` :align: center
that was previously created to be a *child location*, and click :guilabel:`Edit`. :alt: Display stock across all linked warehouses.
Under :guilabel:`Parent Location`, select the virtual warehouse from the drop-down menu, and Example: sell products from a virtual warehouse
:guilabel:`Save` changes. Then, navigate back to the :guilabel:`Locations` overview, and repeat this ===============================================
step for the second physical warehouse stock location. Be sure to :guilabel:`Save` changes again.
Both locations are now *child locations* of the virtual warehouse *parent location*. This allows To sell products from multiple warehouses using a virtual parent location, the database must have at
stock to be taken from multiple locations to fulfill a single sales order, if there is not enough least **two** warehouses configured — with at least **one** product, with quantity on-hand in each
stock in any one location (provided they are both tied to the same virtual warehouse *parent warehouse, respectively.
location*).
Example flow: Sell a product from a virtual warehouse .. example::
===================================================== The following product, `Toy soldier`, is available at each location with the quantities:
.. note:: - `WHA/Stock` : 1
To sell products from multiple warehouses using a virtual *parent* location in this flow, there - `WHB/Stock` : 2
must be at least **two** products and at least **two** warehouses configured - with at least - Warehouses `WHA` and `WHB` are child warehouses of the virtual warehouse `VWH`.
**one** product with quantity on-hand in each warehouse, respectively.
To create a new request for quotation, or RFQ, navigate to the :menuselection:`Sales` app, and Create a quotation for the product by navigating to the :menuselection:`Sales` app and clicking
click :guilabel:`Create` from the :guilabel:`Quotations` overview. Fill out the information on the :guilabel:`Create`. On the quote, add a :guilabel:`Customer`, and click :guilabel:`Add a product` to
new quotation by adding a :guilabel:`Customer`, and click :guilabel:`Add a product` to add the two add the two products stored in the two warehouses.
products stored in the two warehouses.
Then, click the :guilabel:`Other Info` tab on the sales order form. Under the :guilabel:`Delivery` Then, click the :guilabel:`Other Info` tab on the sales order form. Under the :guilabel:`Delivery`
section, change the :guilabel:`Warehouse` field value listed to the virtual warehouse that was section, change the :guilabel:`Warehouse` field value to the virtual warehouse that was
previously created. Once the warehouse has been changed, click :guilabel:`Confirm` to convert the :ref:`previously created <inventory/routes/virtual-wh>`. Next, :guilabel:`Confirm` the sales order.
quotation into a sales order.
Now that the quotation has been confirmed as a sales order, click the :guilabel:`Delivery` smart .. image:: stock_warehouses/set-virtual-wh.png
button. From the warehouse delivery form, confirm that the :guilabel:`Source Location` value matches :align: center
the :guilabel:`Warehouse` field value from the sales order. Both should list the virtual warehouse :alt: Set virtual warehouse as the *Warehouse* field in sales order's *Other Info* tab.
location.
.. important:: Then, click the :guilabel:`Delivery` smart button. From the warehouse delivery form, confirm that
The :guilabel:`Source Location` on the warehouse delivery form and the :guilabel:`Warehouse` the :guilabel:`Source Location` value matches the :guilabel:`Warehouse` field value from the sales
under the :guilabel:`Other Info` tab on the sales order form *must* match in order for the order. Both should list the virtual warehouse location.
products included in the sales order to be pulled from different warehouses.
- If the virtual warehouse is not the value in the :guilabel:`Source Location` field on the Finally, on the warehouse delivery form, under the :guilabel:`Detailed Operations` tab, confirm that
warehouse delivery form, then click :guilabel:`Edit`, make the change, and click the :guilabel:`Locations` in the :guilabel:`From` column for each product match the child locations
:guilabel:`Save`. that are tied to the virtual parent location.
- If the virtual warehouse is not the value in the :guilabel:`Warehouse` field on the sales order,
then a new quotation may need to be generated.
- If the :guilabel:`Warehouse` field is missing on the sales order form, then the virtual
warehouse (and its children warehouses) may not have been set up correctly, in which case,
review the documentation above again to make sure all settings/configuration were done properly.
.. image:: stock_warehouses/stock-warehouses-delivery-order.png .. image:: stock_warehouses/delivery-order.png
:align: center :align: center
:alt: Delivery order with matching source and child locations. :alt: Delivery order with matching source and child locations.
Finally, on the warehouse delivery form, under the :guilabel:`Detailed Operations` tab, confirm .. important::
that the *Locations* values under the :guilabel:`From` column for each product matches to the *child The :guilabel:`Source Location` on the warehouse delivery form, and the :guilabel:`Warehouse`
locations* that are tied to the virtual *parent location*. under the :guilabel:`Other Info` tab on the sales order, **must** match for products in the sales
order to be pulled from different warehouses.
.. note:: - If the virtual warehouse is not in the :guilabel:`Source Location` field on the warehouse
To view which *Locations* the products are coming from on the drop-down menus, click the delivery form, retry product reservation by:
:guilabel:`internal link (arrow)` icon to expand the *Location* information. If needed, it can be
changed from here (granted there is quantity on hand for the product in that location).
Once everything has been properly set, click :guilabel:`Validate` and then :guilabel:`Apply` to - Running the scheduler: turn on :ref:`developer mode <developer-mode>`, and then go to
validate the delivery. Then, navigate back to the sales order form (via the breadcrumbs), and :menuselection:`Inventory app --> Operations --> Run Scheduler`.
click :guilabel:`Create Invoice` to invoice for the sales order. - Clicking :guilabel:`Check Availability` on the delivery order.
- If the virtual warehouse is **not** assigned to the :guilabel:`Warehouse` field on the sales
order, then cancel it, and create a new sales order with the virtual warehouse set in the
:guilabel:`Warehouse` field.
- If the :guilabel:`Warehouse` field is missing on the sales order form, then the multiple child
warehouses may not have been set up correctly. Review the :ref:`previous section
<inventory/routes/child-wh>` to ensure the correct settings.
.. tip:: .. tip::
To use a virtual *parent* location as the default warehouse for sales orders, each salesperson To use a virtual *parent* location as the default warehouse for sales orders, each salesperson
can have the virtual warehouse assigned to them from the drop-down menu next to should have the virtual warehouse assigned to them from the drop-down menu next to
:guilabel:`Default Warehouse` on their employee form. :guilabel:`Default Warehouse` on their employee form.
.. image:: stock_warehouses/stock-warehouses-employee-form.png .. image:: stock_warehouses/stock-warehouses-employee-form.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 21 KiB