[IMP] inventory: sell stock virtual warehouse

closes odoo/documentation#7753

X-original-commit: da19420201
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 7fe59a5ec9
commit 98994fbbaa
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.
.. _inventory/receipts_delivery_one_step/wh:
Configure the warehouse
=======================

View File

@ -30,7 +30,7 @@ The receiving and shipping rules for a one-step configuration are as follows:
- **Receipt**: Receive products directly into stock. No intermediate steps between receipt and stock
occur, such as a transfer to a quality control location.
- **Shipping**: Ship products directly from stock. No intermediate steps between stock and shipping
- **Shipping**: Ship products directly from stock. No intermediate steps between stock and shipping
occur, such as a transfer to a packing location.
- Can only be used if not using :abbr:`FIFO (First In, First Out)`, :abbr:`LIFO (Last In, First
Out)`, or :abbr:`FEFO (First Expired, First Out)` removal strategies.
@ -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.
.. seealso::
:ref:`Process receipts and deliveries in one step <inventory/receipts_delivery_one_step>`
:doc:`receipts_delivery_one_step`
Two-step flow
-------------

View File

@ -6,191 +6,228 @@ 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
locations.
In Odoo, sometimes products included in a single sales order might take stock from two (or more)
warehouses. In Odoo, pulling products from multiple warehouses to satisfy sales demands can be done
by using *virtual locations*.
Sometimes products included in a single sales order might take stock from two (or more) warehouses;
in Odoo, pulling products from multiple warehouses to satisfy sales demands can be done using
*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::
In order to create virtual locations in warehouses and proceed to the following steps,
the :guilabel:`Storage Locations` and :guilabel:`Multi-Step Routes` features will need to be
enabled in the :menuselection:`Settings` app.
In order to create virtual locations in warehouses, and proceed to the following steps, the
:guilabel:`Storage Locations` and :guilabel:`Multi-Step Routes` features **must** be enabled.
To do so, go to :menuselection:`Inventory --> Configuration --> Settings`, scroll down to the
:guilabel:`Warehouse` section, and click the checkboxes next to :guilabel:`Storage Locations`
and :guilabel:`Multi-Step Routes`. Then, :guilabel:`Save` the changes to finish.
To do so, go to :menuselection:`Inventory app --> Configuration --> Settings`, scroll down to the
:guilabel:`Warehouse` section, and enable the :guilabel:`Storage Locations` and
: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
warehouse will act as a *virtual* warehouse, and will be the *parent* location of other physical
warehouses.
.. _inventory/routes/virtual-wh:
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?
Virtual warehouses are great for companies with multiple physical warehouses. This is because
a situation might arise when one warehouse runs out of stock of a particular product, but
another warehouse still has stock on-hand. In this case, stock from these two (or more)
warehouses could be used to fulfill a single sales order.
Virtual warehouses are great for companies with multiple physical warehouses. This is because a
situation might arise when one warehouse runs out of stock of a particular product, but another
warehouse still has stock on-hand. In this case, stock from these two (or more) warehouses could
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
physical warehouses, and is used (for traceability purposes) to create a hierarchy of locations
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
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.
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.
Lastly, click :guilabel:`Save` to finish creating a *regular* warehouse. Continue following the
steps below to finish configuring the virtual parent warehouse.
.. image:: stock_warehouses/stock-warehouses-create-warehouse.png
: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
warehouses, there need to be two warehouses configured with physical stock locations.
.. seealso::
- :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::
| **Parent Warehouse**
| :guilabel:`Warehouse`: `Virtual Warehouse`
| :guilabel:`Location`: `VWH`
| :guilabel:`Location`: `VWH/Stock`
| **Child Warehouses**
| :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::
In order to take stock from multiple warehouses to fulfill a sales order, there need to be at
least **two** warehouses acting as *child locations* of the *virtual parent location* warehouse.
While the virtual stock location will be changed to 'View' later, the :guilabel:`Location Type`
**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`.
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`).
.. _inventory/routes/link-to-vwh:
Then, under the :guilabel:`Additional Information` section, change the :guilabel:`Location Type`
from :guilabel:`Internal Location` to :guilabel:`View`. :guilabel:`Save` the changes.
Link child warehouses to virtual stock
======================================
This identifies this :guilabel:`Location` as a *virtual location*, which is used to create a
hierarchical structure for a warehouse and aggregate its *child locations*.
To set physical warehouses as child locations of the virtual location configured in the
:ref:`previous step <inventory/routes/virtual-wh>`, navigate to :menuselection:`Inventory app -->
Configuration --> Locations`.
.. note::
Products can *not* be stored in a :guilabel:`View` :guilabel:`Location Type`.
Remove any filters from the search bar. Then, click the physical warehouse :guilabel:`Location` that
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
: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
in the :guilabel:`Search Bar`. Then, click into the first physical warehouse :guilabel:`Location`
that was previously created to be a *child location*, and click :guilabel:`Edit`.
.. image:: stock_warehouses/on-hand.png
:align: center
:alt: Display stock across all linked warehouses.
Under :guilabel:`Parent Location`, select the virtual warehouse from the drop-down menu, and
: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.
Example: sell products from a virtual warehouse
===============================================
Both locations are now *child locations* of the virtual warehouse *parent location*. This allows
stock to be taken from multiple locations to fulfill a single sales order, if there is not enough
stock in any one location (provided they are both tied to the same virtual warehouse *parent
location*).
To sell products from multiple warehouses using a virtual parent location, the database must have at
least **two** warehouses configured — with at least **one** product, with quantity on-hand in each
warehouse, respectively.
Example flow: Sell a product from a virtual warehouse
=====================================================
.. example::
The following product, `Toy soldier`, is available at each location with the quantities:
.. note::
To sell products from multiple warehouses using a virtual *parent* location in this flow, there
must be at least **two** products and at least **two** warehouses configured - with at least
**one** product with quantity on-hand in each warehouse, respectively.
- `WHA/Stock` : 1
- `WHB/Stock` : 2
- Warehouses `WHA` and `WHB` are child warehouses of the virtual warehouse `VWH`.
To create a new request for quotation, or RFQ, navigate to the :menuselection:`Sales` app, and
click :guilabel:`Create` from the :guilabel:`Quotations` overview. Fill out the information on the
new quotation by adding a :guilabel:`Customer`, and click :guilabel:`Add a product` to add the two
products stored in the two warehouses.
Create a quotation for the product by navigating to the :menuselection:`Sales` app and clicking
:guilabel:`Create`. On the quote, add a :guilabel:`Customer`, and click :guilabel:`Add a product` to
add the two products stored in the two warehouses.
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
previously created. Once the warehouse has been changed, click :guilabel:`Confirm` to convert the
quotation into a sales order.
section, change the :guilabel:`Warehouse` field value to the virtual warehouse that was
:ref:`previously created <inventory/routes/virtual-wh>`. Next, :guilabel:`Confirm` the sales order.
Now that the quotation has been confirmed as a sales order, click the :guilabel:`Delivery` smart
button. From the warehouse delivery form, confirm that the :guilabel:`Source Location` value matches
the :guilabel:`Warehouse` field value from the sales order. Both should list the virtual warehouse
location.
.. image:: stock_warehouses/set-virtual-wh.png
:align: center
:alt: Set virtual warehouse as the *Warehouse* field in sales order's *Other Info* tab.
.. important::
The :guilabel:`Source Location` on the warehouse delivery form and the :guilabel:`Warehouse`
under the :guilabel:`Other Info` tab on the sales order form *must* match in order for the
products included in the sales order to be pulled from different warehouses.
Then, click the :guilabel:`Delivery` smart button. From the warehouse delivery form, confirm that
the :guilabel:`Source Location` value matches the :guilabel:`Warehouse` field value from the sales
order. Both should list the virtual warehouse location.
- If the virtual warehouse is not the value in the :guilabel:`Source Location` field on the
warehouse delivery form, then click :guilabel:`Edit`, make the change, and click
:guilabel:`Save`.
- 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.
Finally, on the warehouse delivery form, under the :guilabel:`Detailed Operations` tab, confirm that
the :guilabel:`Locations` in the :guilabel:`From` column for each product match the child locations
that are tied to the virtual parent location.
.. image:: stock_warehouses/stock-warehouses-delivery-order.png
.. image:: stock_warehouses/delivery-order.png
:align: center
:alt: Delivery order with matching source and child locations.
Finally, on the warehouse delivery form, under the :guilabel:`Detailed Operations` tab, confirm
that the *Locations* values under the :guilabel:`From` column for each product matches to the *child
locations* that are tied to the virtual *parent location*.
.. important::
The :guilabel:`Source Location` on the warehouse delivery form, and the :guilabel:`Warehouse`
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::
To view which *Locations* the products are coming from on the drop-down menus, click the
: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).
- If the virtual warehouse is not in the :guilabel:`Source Location` field on the warehouse
delivery form, retry product reservation by:
Once everything has been properly set, click :guilabel:`Validate` and then :guilabel:`Apply` to
validate the delivery. Then, navigate back to the sales order form (via the breadcrumbs), and
click :guilabel:`Create Invoice` to invoice for the sales order.
- Running the scheduler: turn on :ref:`developer mode <developer-mode>`, and then go to
:menuselection:`Inventory app --> Operations --> Run Scheduler`.
- 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::
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.
.. image:: stock_warehouses/stock-warehouses-employee-form.png
:align: center
:alt: Default warehouse location on employee form.
.. image:: stock_warehouses/stock-warehouses-employee-form.png
:align: center
:alt: Default warehouse location on employee form.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 21 KiB